线段树+离散化。
#include <cstdio>
#include <cstring>
#include <cstdlib> #define MAXN 20005
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 int buf[MAXN], bk[MAXN];
int sum[MAXN<<], n; int comp(const void *a, const void *b) {
return *(int *)a - *(int *)b;
} void PushUP(int rt) {
sum[rt] = sum[rt<<] + sum[rt<<|];
} void build(int l, int r, int rt) {
sum[rt] = ;
if (l == r)
return ;
int mid = (l+r)>>;
build(lson);
build(rson);
} int query(int ll, int rr , int l, int r, int rt) {
if (ll<=l && r<=rr)
return sum[rt];
int mid = (l+r)>>;
int ret = ;
if (ll <= mid)
ret += query(ll, rr, lson);
if (rr > mid)
ret += query(ll, rr, rson);
return ret;
} void update(int x, int l, int r, int rt) {
if (l == r) {
++sum[rt];
return ;
}
int mid = (l+r)>>;
if (x <= mid)
update(x, lson);
else
update(x, rson);
PushUP(rt);
} int getIndex(int x) {
int l=, r=n, mid; while (l <= r) {
mid = (l+r)>>;
if (bk[mid] == x)
return mid;
if (x > bk[mid])
l = mid + ;
else
r = mid - ;
}
return ;
} int main() {
int t;
int i;
int index;
__int64 ll, lg, rl, rg;
__int64 ans; scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (i=; i<=n; ++i) {
scanf("%d", &buf[i]);
bk[i] = buf[i];
}
build(, n, );
qsort(bk+, n, sizeof(int), comp);
ans = ;
for (i=; i<=n; ++i) {
index = getIndex(buf[i]);
ll = query(, index, , n, );
lg = i--ll;
rl = index--ll;
rg = n-index-lg;
ans += ll*rg + lg*rl;
update(index, , n ,);
}
printf("%I64d\n", ans);
} return ;
}