题意:训练指南P197
分析:枚举裁判的位置,用树状数组来得知前面比它小的和大的以及后面比它小的和大的,然后O (n)累加小 * 大 + 大 * 小 就可以了
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e5 + 5; const int M = 2e4 + 5; struct BIT { int c[N], sz; void init(int n) { memset (c, 0, sizeof (c)); sz = n; } void updata(int i, int x) { while (i <= sz) { c[i] += x; i += i & -i; } } int query(int i) { int ret = 0; while (i) { ret += c[i]; i -= i & -i; } return ret; } }bit; int a[M], small[M][2], large[M][2]; int main(void) { int T; scanf ("%d", &T); while (T--) { bit.init (100000); int n; scanf ("%d", &n); for (int i=1; i<=n; ++i) { scanf ("%d", &a[i]); small[i][0] = bit.query (a[i] - 1); large[i][0] = i - 1 - small[i][0]; bit.updata (a[i], 1); } for (int i=1; i<=n; ++i) { small[i][1] = bit.query (a[i] - 1) - small[i][0]; large[i][1] = n - i - small[i][1]; } ll ans = 0; for (int i=1; i<=n; ++i) { ans += 1ll * small[i][0] * large[i][1]; ans += 1ll * large[i][0] * small[i][1]; } printf ("%lld ", ans); } return 0; }