题意分析
用树状数组写了一遍哈
常数小不少,线段树400ms,树状数组100ms
代码总览
#include <bits/stdc++.h>
#define mem(x,y) memset (x,y,sizeof x)
#define rep(i,a,b) for (int i = a; i<=b; ++i)
using namespace std;
const int nmax = 1e6 + 10;
const int INF = 0x3f3f3f3f;
typedef long long ll;
typedef double db;
int tree[nmax], L[nmax], R[nmax], a[nmax];
int t, n;
inline int lowbit(int x) {return x & (-x);}
int querysum(int x) {
int ans = 0;
while ( x > 0 ) {
ans += tree[x];
x -= lowbit(x);
}
return ans;
}
void add(int pos , int val) {
while (pos <= 100001) {
tree[pos] += val;
pos += lowbit(pos);
}
}
int main() {
scanf("%d", &t);
while (t--) {
mem(tree, 0);
mem(L, 0); mem(R, 0);
scanf("%d", &n);
rep(i, 1, n) scanf("%d", &a[i]);
rep(i, 1, n) {
L[i] = querysum(a[i]);
add(a[i], 1);
}
mem(tree, 0);
for (int i = n; i >= 1; --i) {
R[i] = querysum(a[i]);
add(a[i], 1);
}
ll ans = 0;
rep(i, 1, n) {
if (i == 1 || i == n) continue;
ans += L[i] * ((ll)n - i - R[i]);
ans += R[i] * ((ll)i - 1 - L[i]);
}
printf("%lld\n", ans);
}
return 0;
}