分治法:归并排序求逆序对

现给出这个定义,什么是逆序对,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 }

关于归并排序的代码实现原理以及求逆序对的原理将在后续补充。

posted @ 2018-07-13 16:43  静听风吟。  阅读(286)  评论(0编辑  收藏  举报