思路
归并排序是一种分治思想,把一个数组分成左右两边分别排序,然后在合并,我们在合并的时候考虑,对于右边的坐标r_1,左边比右边大的个数不就是mid-l_1+1,每次求和就可以
#include <iostream>
using namespace std;
const int MAXN=1e7+10;
typedef long long ll;
ll num[MAXN];
ll num1[MAXN];
ll ans;
void mergeSort(ll l,ll r)
{
if(l==r) return;
ll mid=(l+r)/2;
mergeSort(l,mid);
mergeSort(mid+1,r);
ll l_1=l,r_1=mid+1;
for(ll i=0;i<(r-l+1);i++)
{
if(l_1>mid) num1[i]=num[r_1++];
else if(r_1>r) num1[i]=num[l_1++];
else if(num[l_1]<=num[r_1]) num1[i]=num[l_1++];
else num1[i]=num[r_1++],ans+=(mid-l_1+1);
}
for(ll i=l;i<=r;i++)
num[i]=num1[i-l];
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
ans=0;
ll n;
scanf("%lld",&n);
for(int i=0;i<n;i++)
scanf("%lld",&num[i]);
mergeSort(0,n-1);
printf("%lld\n",ans);
}
return 0;
}