大体思路就是枚举裁判位置,找逆序对数。
练习一下用树状数组来寻找逆序对
#include <cstdio> #include <cstring> #include <iostream> #define lowbit(x) ((x)&(-x)) using namespace std; const int maxi = 100005; const int maxn = 20001; int C[maxi],num[maxn],n; int l[maxn],r[maxn]; inline void add(int x,int d) { while(x <= maxi) { C[x] += d; x += lowbit(x); } } inline int sum(int x) { int ans = 0; while(x > 0) { ans += C[x]; x -= lowbit(x); } return ans; } int main() { int T; scanf("%d",&T); while(T--) { long long ans = 0; scanf("%d",&n); memset(C,0,sizeof(C)); for(int i = 1;i <= n;i++) scanf("%d",num + i); for(int i = 1;i <= n;i++) { add(num[i],1); l[i] = sum(num[i] - 1); } memset(C,0,sizeof(C)); for(int i = n;i >= 1;i--) { add(num[i],1); r[i] = sum(num[i] - 1); } for(int i = 2;i < n;i++) { ans += l[i] * (n - i - r[i]) + r[i] * (i - 1 - l[i]); } cout << ans << endl; } return 0; }