用归并排序,分治的思想,在每一次将要合并两个数组之前,在两个已经排好顺序的数组中记录满足条件的个数。
第一次数组开小了re,第二次ans没有用long long有wa了
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=5*1e5+10;
int a[maxn];
ll ans;
void mergesort(int arr1[],int l,int r)
{
if(l>=r) return;
int mod=(l+r)>>1;
mergesort(arr1,l,mod);
mergesort(arr1,mod+1,r);
//先比较下一层的已经排好的顺序,从小到大排
int i,j;
for(i=mod,j=r;i>=l&&j>=mod+1;){
if(arr1[i]>arr1[j]){
ans+=(ll)(j-mod);
i--;
}
else j--;
}
int* arr2=(int*)malloc(sizeof(int)*(r-l+1));
i=l,j=mod+1;
int k=0;
while(i<=mod&&j<=r){
if(arr1[i]<arr1[j]) arr2[k++]=arr1[i++];
else arr2[k++]=arr1[j++];
}
while(i<=mod){
arr2[k++]=arr1[i++];
}
while(j<=r){
arr2[k++]=arr1[j++];
}
for(i=l,j=0;i<=r;++i,++j){
arr1[i]=arr2[j];
}
free(arr2);
}
int main()
{
int n,i,j,k;
cin >> n;
for(i=0;i<n;i++)
scanf("%d",&a[i]);
mergesort(a,0,n-1);
printf("%lld\n",ans);
return 0;
}