求逆序对数的两种方法
2013-08-18 07:51
274 查看
1.通过树状数组
2.利用归并排序的思想,二分法得到逆序对数
以上两种方法都比较高效,注意法二中cnt一定要是全局变量,且调用之前一定别忘了清零,否则会出错(可以想想原因)
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int maxn=2000; int n,tree[maxn]; int lowbit(int i) { return i&(-i); } void update(int i,int x) { while(i<=n) { tree[i]+=x; i+=lowbit(i); } } int query(int i) { int ans=0; while(i>0) { ans+=tree[i]; i-=lowbit(i); } return ans; } int main() { int i,sum,x; while(~scanf("%d",&n)&&n) { sum=0; memset(tree,0,sizeof(tree)); for(i=1;i<=n;i++) { scanf("%d",&x); update(x,1); sum+=i-query(x); } printf("%d\n",sum); } }
2.利用归并排序的思想,二分法得到逆序对数
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; const int maxn=1000; int a[maxn],t[maxn],cnt; int invertnum(int *a,int x,int y,int *t) { if(y-x>1) { int m=x+(y-x)/2; int l=x,r=m,i=x; invertnum(a,x,m,t); invertnum(a,m,y,t); while(l<m||r<y) { if(r>=y||(l<m&&a[l]<=a[r])) t[i++]=a[l++]; else{ t[i++]=a[r++]; cnt+=m-l; } } for(i=x;i<y;i++) a[i]=t[i]; } return cnt; } int main() { int n; while(~scanf("%d",&n)) { cnt=0; for(int i=0;i<n;i++) scanf("%d",&a[i]); int k=invertnum(a,0,n,t); for(int i=0;i<n;i++) printf("%d ",a[i]); printf("\n%d\n",k); } }
以上两种方法都比较高效,注意法二中cnt一定要是全局变量,且调用之前一定别忘了清零,否则会出错(可以想想原因)
相关文章推荐
- 归并排序求逆序对数 (附另两种姿势BIT 线段树)
- java两种方法将一个字符串逆序
- 单链表反转/逆序的两种方法
- 不带头节点链表逆序的两种方法
- 单链表反转/逆序的两种方法
- 两种方法实现单向链表的创建、遍历、删除、查找、逆序输出(循环法和递归法)
- C++输入一个字符串,把其中的字符按照逆序输出的两种方法
- 单链表反转/逆序的两种方法
- 两种方法求单链表逆序
- 两种字符串逆序的方法
- 单链表反转/逆序的两种方法
- C语言:链表的逆序,两种思考方法,第一种用rev_1()实现,第二种用rev_2( )实现.
- C++输入一个字符串,把其中的字符按照逆序输出的两种方法
- 单链表反序,逆序的两种方法
- 实现数组逆序排列的两种方法
- C++输入一个字符串,把其中的字符按照逆序输出的两种方法
- C++输入一个字符串,把其中的字符按照逆序输出的两种方法
- C++输入一个字符串,把其中的字符按照逆序输出的两种方法解析
- 笔记③:POJ Roadblocks 次短路问题代码解析(优先队列逆序排列两种方法)
- 求解逆序对数的几种方法