#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1000010;
int p[N],temp[N];
int n;
typedef long long LL;
LL mergeSort(int p[],int l,int r){
if(l>=r) return 0;
int mid = (l+r)>>1;
//只有合并的时候才会进行元素之间的大小的比较
//res存储的是上一区间的结果;
LL res = mergeSort(p,l,mid) + mergeSort(p,mid+1,r);
//下面进行两个区间合并操作
int cnt=0,i=l,j=mid+1;
while(i<=mid && j<=r){
if(p[i]<=p[j]) temp[cnt++] = p[i++];
else{//这里的i总是指的是前面的区间的数值,因此这里进行比较的时候总前面
//前面的数与后面的数进行比较:
temp[cnt++] = p[j++];
//因为此时的前半个区间的数值已经是排序好的
//因此如果p[i]>p[j],并且i<mid
//那么i-mid这个区间内的所有的数值都要>p[j]
//因此每次记录的是i-mid这个区间的所有的数的总的个数
res+=mid-i+1;//这区间内的总的个数;
//这里返回的是每个小区间的逆序对的总的数量
}
}
while(i<= mid) temp[cnt++] = p[i++];
while(j<= r) temp[cnt++] = p[j++];
//这里的下标搞错了应该从l开始,并不应该从0开始进行数组的循环;
for(int i=0,j=l;i<cnt;i++,j++){
p[j] = temp[i];
}
return res;
}
int main(){
cin>>n;
for(int i=0;i<n;i++)
scanf("%d",&p[i]);
LL res =mergeSort(p,0,n-1);
cout<<res<<endl;
return 0;
}
788. 逆序对的数量
于 2024-02-28 10:09:12 首次发布