解题关键:就是利用分治的思想,使用归并排序,因为逆序对实际上就是“左侧的数字比右侧大就算一个逆序对”。而这个“左侧”和“右侧”可以相对来看,即左侧的左侧一定就是左侧,说的有点抽象,哈哈哈哈。
花了个示意图,也很抽象,哈哈哈哈,仅供参考。
#include<bits/stdc++.h>
using namespace std;
int n,data[500010],has[500010];
long long ans;
void msort(int b,int e){
if(b==e){
return;
}
int mid=(b+e)/2;
int i=b;
int j=mid+1;
int k=b;
msort(b,mid);
msort(mid+1,e);
while(i<=mid&&j<=e){
//将左右两个序列进行比较,把较大的接在has之后
if(data[i]<=data[j]){
has[k++]=data[i++];
}else{
has[k++]=data[j++];
ans+=mid-i+1;
}
}
//将剩下的进行归并
while(i<=mid){
has[k++]=data[i++];
}
while(j<=e){
has[k++]=data[j++];
}
//将排好序的序列has规划给原本的序列data
for(int l=b;l<=e;l++){
data[l]=has[l];
}
}
int main(void){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&data[i]);
}
msort(1,n);
printf("%lld",ans);
return 0;
}