树状数组,前后统计比当前位置的大小的个数,然后累乘,再相加
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
#define LLEN 100004
int num[LLEN];
int a[LLEN];
int lowbit(int x) {
return x & (-x);
}
void update(int pos) {
while(pos <= LLEN) {
a[pos]++;
pos += lowbit(pos);
}
}
int query(int pos) {
int sum = 0;
while(pos > 0) {
sum += a[pos];
pos -= lowbit(pos);
}
return sum;
}
int main() {
int t;
int c[LLEN], d[LLEN];
scanf("%d", &t);
while(t--) {
int n;
scanf("%d", &n);
memset(c, 0, sizeof(c));
memset(d, 0, sizeof(d));
memset(a, 0, sizeof(a));
memset(num, 0, sizeof(num));
for(int i = 1; i <= n; i++) {
scanf("%d", &num[i]);
}
for(int i = 1; i <= n; i++) {
update(num[i]);
c[i] = query(num[i]-1);
}
memset(a, 0, sizeof(a));
for(int i = n; i >= 1; i--) {
update(num[i]);
d[i] = query(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];
}
if(ans <= 0) ans = 0;
printf("%lld\n", ans);
}
return 0;
}