UVAlive - 4329 —— Ping pong 【树状数组】
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=13895
#include <iostream> #include <cstdio> #include <cstring> #include <string> using namespace std; const int MAXA = 100000 + 5; int n; int c[MAXA]; int sum(int i) { int ret = 0; while(i > 0) { ret += c[i]; i -= i & (-i); } return ret; } void add(int i, int d) { while(i <= MAXA-1) { c[i] += d; i += i & (-i); } } int main () { int T; int *a, *leftLess, *rightLess; scanf("%d", &T); while(T--) { scanf("%d", &n); a = new int[n]; leftLess = new int[n]; rightLess = new int[n]; for(int i=0; i<n; i++) { scanf("%d", &a[i]); leftLess[i] = sum(a[i]-1); add(a[i], 1); } memset(c, 0, sizeof(c)); for(int i=n-1; i>=0; i--) { rightLess[i] = sum(a[i]-1); add(a[i], 1); } long long ret = 0; for(int i=0; i<n; i++) { // a[i] is distinct integers, so the opsite side of leftLess is leftGreater ret += leftLess[i] * 1LL * (n-1-i-rightLess[i]); ret += (i-leftLess[i]) * 1LL * rightLess[i]; } printf("%lld\n", ret); memset(c, 0, sizeof(c)); delete(a); delete(leftLess); delete(rightLess); } return 0; }