归并排序求逆序对
详细解释在代码注释里面
本题主要注意的是$ans$要开$longlong$
#include<bits/stdc++.h>
using namespace std;
int n,a[600000],b[600000];
long long ans;
void merge_sort(int l,int r){
if (l==r) return;
int mid=(l+r)/2;
//往下递归
merge_sort(l,mid);
merge_sort(mid+1,r);
//排序
int i=l,j=mid+1,k=l;//操作更新的是l->r的区间 初值赋在l和r
while (i<=mid&&j<=r){//在底层递归结束之后 前后两个部分都应该是有序的
if (a[i]<=a[j]) {
b[k]=a[i];//把较小的数据放入辅助数组
i++;
k++;
}
else {
b[k]=a[j];
ans+=mid-i+1;//前一半是有序的那么这个后面的都是逆序对
j++;
k++;
}
}
//剩余元素加入数组
while(i<=mid) {
b[k]=a[i];
k++;
i++;
}
while (j<=r){
b[k]=a[j];
k++;
j++;
}
for (int p=l;p<=r;p++) a[p]=b[p];
}
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
merge_sort(1,n);
printf("%lld\n",ans);
return 0;
}