思路

可以顺便把这道一模一样的题给A掉Luogu P5463 小鱼比可爱(加强版)
各位可以做完《逆序数》再过来,我是用归并排序写的。
考虑到对于一个逆序对<i,j>,i∈[l,m],j∈[m+1,r],那么它是所有区间[x,y],x∈[l,i],y∈[j,r]中的逆序对,
每一次merge计算逆序对的时候都乘以外面的区间数(L*(n-R+1)),就是那些逆序对的总贡献。
###代码

#include<bits/stdc++.h>
#define int __int128
using namespace std;
typedef long long ll;
const int maxn=1e6+5;

struct X{
    int id,val;
}a[maxn],tmp[maxn];

int n,ans=0,sum=0;

inline void write(int x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}

void merge(int l,int m,int r){
    int i=l,j=m+1,k=l;
    ll sum=0;
    for(int i=l;i<=m;i++){
        sum+=a[i].id;
    }
    while(i<=m&&j<=r){
        if(a[i].val>a[j].val){
            ans+=sum*(n-a[j].id+1);
            tmp[k++]=a[j++];
        }else{
            sum-=a[i].id;
            tmp[k++]=a[i++];
        }
    }
    while(i<=m) tmp[k++]=a[i++];
    while(j<=r) tmp[k++]=a[j++];
    for(int i=l;i<=r;i++) a[i]=tmp[i];
}

void merge_sort(int l,int r){
    if(l==r) return;
    int mid=l+r>>1;
    merge_sort(l,mid);
    merge_sort(mid+1,r);
    merge(l,mid,r);
}

signed main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i].val);
        a[i].id=i;
    }
    merge_sort(1,n);
    write(ans);
    return 0;
}