用树状数组统计每个点i,左边与右边与多少个点小于a[i],然后用乘法原理和加法原理得出答案
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define ll long long
#define ls(i) i<<1
#define rs(i) i<<1|1
using namespace std;
const int N = 1e5+10;
ll bit[N],lx[N],rx[N],a[N];
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int val)
{
while(x<N)
{
bit[x]+=val;
x+=lowbit(x);
}
}
ll query(int x)
{
ll ans=0;
while(x>0)
{
ans+=bit[x];
x-=lowbit(x);
}
return ans;
}
int main(){
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
memset(bit,0,sizeof(bit));
for(int i=1;i<=n;i++)
{
lx[i]=query(a[i]);
add(a[i],1);
}
memset(bit,0,sizeof(bit));
for(int i=n;i>=1;i--)
{
rx[i]=query(a[i]);
add(a[i],1);
}
ll ans=0;
for(int i=1;i<=n;i++)
{
ans+=lx[i]*(n-i-rx[i])+(i-lx[i]-1)*rx[i];
}
cout<<ans<<"\n";
}
return 0;
}
知识兔