//2492 Ping pong 线段树+离散化
/*
题意:
有一陀人从左到右排成一排,每个人有一个唯一的技能值,每个人都找其他人比赛,
比赛前要再找一个人做裁判,裁判的技能值不能比这两个人都高,也不能比这两个人都低,
并且这两个人到裁判的距离总和不能大于他们之间的距离,
不同的人比赛或者比赛时候的裁判不同算不同的比赛,求一共能比几场
思路:
由题意知道裁判必须在这两个人中间
枚举每一个人做裁判,这是能发生的比赛就是
1、这个人之前技能值比他小的*这个人之后技能值比他大的
2、这个人之前技能值比他大的*这个人之后技能值比他小的
由于技能值不是从1-n,所以要离散化
总数多 要__int64
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 20005
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
int sum[N<<2],s[N],x[N];
int n;
int cmp(const void *a,const void *b){
return *(int *)a - *(int *)b;
}
void Pushup(int rt){
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void Build(int rt,int l,int r){
sum[rt] = 0;
if(l == r)
return ;
int mid = (l + r) >> 1;
Build(lson);
Build(rson);
}
void Update(int rt,int l,int r,int x){
if(l == r){
++sum[rt];
return ;
}
int mid = (l + r) >>1;
if(x <= mid) Update(lson,x);
else Update(rson,x);
Pushup(rt);
}
__int64 Query(int rt,int l,int r,int L,int R){
if(L <= l && R >= r){
return sum[rt];
}
int mid = (l + r) >> 1;
__int64 res = 0;
if(L <= mid) res += Query(lson,L,R);
if(R > mid ) res += Query(rson,L,R);
return res;
}
int Bin(int key){
int l = 1,r = n,mid;
while(r >= l){
mid = (l + r ) >> 1;
if(key == s[mid]) return mid;
if(key > s[mid]) l = mid + 1;
else r = mid - 1;
}
return -1;
}
int main(){
int T,i,tmp;
__int64 ans,a,b,c,d;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
Build(1,1,n);
ans = 0;
for(i = 1; i <= n; ++i){
scanf("%d",&s[i]);
x[i] = s[i];
}
qsort(s+1,n,sizeof(s[0]),cmp);
for(i = 1; i <= n; ++i){
tmp = Bin(x[i]);
a = Query(1,1,n,1,tmp); //前面比它小的
b = i-1-a; //前面比它大的
c = tmp-1-a; //后面比它小的
d = n-tmp-b; //后面比它大的
ans += a*d+b*c;
Update(1,1,n,tmp);
}
printf("%I64d\n",ans);
}
return 0;
}