现给出这个定义,什么是逆序对,NOIP火柴排队这个题是逆序对的一个比较好的例题,这里我们只讨论求逆序对的一些高效的算法
一般有归并排序以及树状数组两种方法,本文只讨论归并排序求逆序对
这里不给出原理只给出实现,注意下面这一句
ans+=m-p;
把这句话加在归并排序的合并过程中即可,下面给出实现代码:
1 #include<iostream> 2 using namespace std; 3 const int maxn=100005; 4 int n; 5 int a[maxn]; 6 long long ans=0; 7 int t[maxn]; 8 void count(int* A,int x,int y) 9 { 10 if(x+1<y) 11 { 12 int m=(x+y)/2; 13 count(A,x,m); 14 count(A,m,y); 15 int p=x,q=m; 16 int i=x; 17 while(p<m||q<y) 18 { 19 if(q>=y||(p<m&&A[p]<=A[q])) 20 t[i++]=A[p++]; 21 else 22 { 23 t[i++]=A[q++]; 24 ans+=m-p; 25 } 26 } 27 for(int i=x;i<y;i++) A[i]=t[i]; 28 } 29 } 30 int main() 31 { 32 cin>>n; 33 for(int i=0;i<n;i++) cin>>a[i]; 34 count(a,0,n); 35 cout<<ans<<endl; 36 return 0; 37 }
关于归并排序的代码实现原理以及求逆序对的原理将在后续补充。