hdu 1394 求逆序数(线段树求)
来源:互联网 发布:树莓派和单片机的区别 编辑:程序博客网 时间:2024/06/05 14:12
http://acm.hdu.edu.cn/showproblem.php?pid=1394
题意描述:给你一个有0--n-1数字组成的序列,然后进行这样的操作,每次将最前面一个元素放到最后面去会得到一个序列,那么这样就形成了n个序列,那么每个序列都有一个逆序数,找出其中最小的一个输出!
解析:
求出a1, a2, ..., an-1, an的逆序数之后,就可以递推求出其他序列的逆序数。 假设要把a1移动到an之后,那么我们把这个过程拆分成两步:
1. 把a1去除掉。通过观察可以发现,(a1-1)是0~n-1中比a1小的数字的个数,由于a1在序列的第一个所以a1之后共有(a1-1)个比a1小,所以形成了(a1-1)对逆序数,当去除掉a1时,原序列的逆序数总数也就减少了(a1-1)个逆序数。
2. 把a1加到an之后。0~n-1中,比a1大的数共有(n-a1)个数,由于a1现在在最后一个,也就是它前面共有(n-a1)个数比它大,即增加了(n-a1)对逆序数。
综合1,2两步, 设原序列逆序数为sum, 当把原序列第一个移动到最后位置时,逆序数变为:sum = sum-(ai-1)+(n-ai);
3.由于此题范围是0到n-1;所以sum = sum -(ai) + (n - 1 - ai);
#include<cstdio> #include<cstring> using namespace std; const int N = 5050; struct node { int l,r; int num; //表示该区间已经出现节点的个数 }tree[N*4]; void bulid(int rt ,int l,int r) { tree[rt].l=l; tree[rt].r=r; tree[rt].num=0; if(l==r) return; int mid = (l+r)/2; bulid(2*rt,l,mid);//创建左子树 bulid(2*rt+1,mid+1,r); } int search(int rt, int l,int r) { if(l>r) return 0; if(l==tree[rt].l&&r == tree[rt].r) return tree[rt].num; int mid = (tree[rt].l+tree[rt].r)/2; if(r<=mid) return search(2*rt,l,r); else if(l>mid) return search(2*rt+1,l,r); else return search(2*rt,l,mid)+search(2*rt+1,mid+1,r); } void update(int rt, int x) { tree[rt].num++; if(tree[rt].l==tree[rt].r) return; int mid = (tree[rt].l+tree[rt].r)/2; if(x<=mid) update(2*rt,x); else update(2*rt+1,x); } /*void print(int rt) { printf("%d %d %d\n",tree[rt].l, tree[rt].r , tree[rt].num); if(tree[rt].l==tree[rt].r) return; print(2*rt); print(2*rt+1); }*/ int main () { int a[N]; int n; int i, min; while(scanf("%d",&n)!=EOF) { bulid(1,0,n-1); int sum = 0; for(i=0;i<n;i++) scanf("%d",&a[i]); for(i=0;i<n;i++) { sum+=search(1,a[i]+1,n-1);//查找在a[i]之前出现且比a[i]大的数 // cout << sum << endl; update(1,a[i]); } min =sum; for(i=0;i<n-1;i++) { sum += (n-a[i]-1)-a[i]; if(min>sum) min =sum; } printf("%d\n",min); } return 0; }
0 0
- hdu 1394 求逆序数(线段树求)
- hdu 1394(线段树求逆序数)
- hdu 1394 线段树 求逆序数
- hdu 1394 线段树求逆序数
- hdu 1394 线段树求逆序数
- HDU 1394 线段树求逆序数
- HDU 1394 线段树求逆序数
- HDU 1394 Minimum Inversion Number 线段树求逆序数
- hdu 1394 用线段树求逆序数
- HDU 1394 线段树单点更新求逆序数
- hdu 1394 Minimum Inversion Number 线段树求逆序数
- HDU 1394(单点更新线段树求逆序数)
- 线段树求逆序数 hdu 1394 Minimum Inversion Number
- HDU 1394 Minimum Inversion Number【线段树求逆序数】
- HDU 1394- Minimum Inversion Number(线段树求逆序数)
- HDU 1394 Minimum Inversion Number // 线段树求逆序数
- HDU 1394 Minimum Inversion Number(线段树求逆序数)
- hdu 1394 Minimum Inversion Number 线段树求逆序数
- 黑马程序员 —— Java高级视频_IO输入与输出(第十九天)1
- Struts2之单文件上传
- 懒加载
- 黑马程序员 —— Java高级视频_IO输入与输出(第十九天)2
- 如何安装Ubuntu14.04操作系统及Chromium浏览器、FlashPlayer插件
- hdu 1394 求逆序数(线段树求)
- Ubuntu using Ramdisk for better performance and fast response
- 招聘QT+opencv联合编程人员
- CashWithdraw
- 黑马程序员 —— Java高级视频_IO输入与输出(第二十天)
- HGE引擎---hgeAnimation动画精灵
- 黑马程序员 —— Java高级视频_IO输入与输出(第二十一天)
- MVC学习系列-表单的异步提交
- 如何使用online account来创建微博Scope