大白书上的原题,用树状数组统计出i两边有多少比num[i]小的,由乘法原理和加法原理就可得;
终于看懂树状数组了~~
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn=100050;
int num[maxn];
long long a[maxn];
long long c[maxn];
long long d[maxn];
int lowbit(int x){
return x&(-x);
}
int sum(int x){
long long ans=0;
while(x>0){
ans+=a[x];
x-=lowbit(x);
}
return ans;
}
void add(int x,int d){
while(x<maxn){
a[x]+=d;
x+=lowbit(x);
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
memset(a,0,sizeof(a));
memset(num,0,sizeof(num));
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
}
for(int i=1;i<=n;i++){
add(num[i],1);
c[i]=sum(num[i]-1);
}
memset(a,0,sizeof(a));
for(int i=n;i>0;i--){
add(num[i],1);
d[i]=sum(num[i]-1);
}
long long ans=0;
for(int i=1;i<=n;i++){
ans+=(c[i]*(n-i-d[i])+(i-c[i]-1)*d[i]);
}
printf("%lld\n",ans);
}
return 0;
}