归并排序,思路简单,百度一下到处都是。
计算有多少组思路如下:
对于一个已经排好的两个序列(A,B)而言,因为A中序列数字在原序列的位置都是在B之前的,所以,每次从B中取元素时,A中有多少个没有取,就说明A中这些元素都能和当前从B取的这个元素组成一对逆序数,然后统计每次从B中取元素时的A有多少没取,然后直接输出答案。
归并排序思路如下:
对于每一个序列可以尽量平分成为两个子序列,然后每个子序列也可以如此操作,然后直到不可拆分为止,从两个子序列中从小到大依次取元素(此时每个子序列都只有一个元素),然后把合并的新序列返回到原序列,这样原序列对应的这段元素就是排好序的,然后依次类推。
代码如下:(最近又改了一下代码,发现以前写的代码好难看啊,虽然现在也难看,但是勉强能入眼吧......)
#include<bits/stdc++.h>
using namespace std;
int n,num[50005],Count[50005],ans;
void find(int S,int mid,int E){
int s=S,m=mid+1,e=E,k=s;
while(s<=mid && m<=e){
if(num[s]<=num[m]) Count[k++]=num[s++];
else {
Count[k++]=num[m++];
ans+=mid-s+1;
}
}
while(s<=mid)Count[k++]=num[s++];
while(m<=e)Count[k++]=num[m++];
for(s=S;s<=E;s++)num[s]=Count[s];
//printf("%d %d %d %d\n",S,mid,E,ans);
}
void Msort(int S,int E){
if(S>=E)return ;
int mid=(S+E)/2;
Msort(S,mid);
Msort(mid+1,E);
find(S,mid,E);
}
int main(){
ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
}
Msort(1,n);
printf("%d\n",ans);
}