逆序数:比如5 2 4 逆序数为 2 ,5比2大算为一次,两两比较。
归并思路: 我们先观察两个数, 它们可能被分为同一侧,也可能在中点的两侧;
当它们分别在中点的两侧时, 当q[i] 大于q[j] 时, q[i]后面的每一个数都大于q[j];
即此时的归并数为res=mid-i+1
#include <iostream>
using namespace std;
typedef long long LL;
const int N =10010;
int n,q[N],tem[N];LL merge_sort(int l,int r)
{
if(l>=r) return 0;
int mid=l+r>>1;
LL res = merge_sort(l,mid)+merge_sort(mid+1,r);
int k=0,i=l,j=mid+1;
while((i<=mid&&j<=r))
if(q[i]<=q[j]) tem[k++]=q[i++];
else {
tem[k++] =q[j--];
res+=mid-i+1;
}
while(q[i]<=mid) tem[k++]=q[i++];
while(q[j]>=r) tem[k++]=q[j++];
for(int i=l,j=0;i<r;i++,j++)
{
q[i]=tem[j];
}
return res;
}int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&q[i]);
cout<<merge_sort(0,n-1)<<endl;
return 0;
}