#include<iostream>
using namespace std;
int t[40005],ans=0;
void merge(int a[],int l,int r){//归并大法
if(l==r)
return;
int mid=(l+r)/2;
merge(a,l,mid);//用分治的思想,先分离,再合并
merge(a,mid+1,r);
int i=l,j=mid+1,p=l;
while(i<=mid&&j<=r){
if(a[i]>a[j]){
t[p++]=a[j++];
ans+=mid-i+1;//此时两边都是排好序了的,当前面的序列中有一个数大于后面的一个数时,前面序列中剩下的数都大于这个数,共mid-i+1个
}
else
t[p++]=a[i++];
}
while(i<=mid)
t[p++]=a[i++];//把序列中剩下的数存入t
while(j<=r)
t[p++]=a[j++];
for(i=l;i<=r;i++)
a[i]=t[i];//t中的数要回到a中
}
int main(){
int n,a[40005];
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
merge(a,1,n);//调用merge
cout<<ans<<endl;
return 0;
}
P1908 逆序对
2019-05-10