Ultraviolet A 1428-ping pong
Question Link
Question: given some people, from left to right, each person has a skill value. To hold a competition, you must meet the requirements of three people from left to right, in addition, the skill value ranges from small to large or from large to small.
Idea: Use a tree array to process the number and sum of numbers smaller than the left and smaller than the right of each position, so that the numbers on the left and right can also be calculated, the number of matches is small on the left * big on the right + big on the left * small on the right.
Code:
#include <cstdio>#include <cstring>const int N = 100005;int t, n, a[N];long long bit[N], lx[N], rx[N];inline int lowbit(int x) { return x&(-x);}void add(int x, long long val) { while (x < N) {bit[x] += val;x += lowbit(x); }}long long Query(int x) { long long ans = 0; while (x > 0) {ans += bit[x];x -= lowbit(x); } return ans;}int main() { scanf("%d", &t); while (t--) {scanf("%d", &n);memset(bit, 0, sizeof(bit));for (int i = 0; i < n; i++) { scanf("%d", &a[i]); lx[i] = Query(a[i]); add(a[i], 1);}memset(bit, 0, sizeof(bit));for (int i = n - 1; i >= 0; i--) { rx[i] = Query(a[i]); add(a[i], 1);}long long ans = 0;for (int i = 0; i < n; i++) ans += lx[i] * (n - i - 1 - rx[i]) + (i - lx[i]) * rx[i];printf("%lld\n", ans); } return 0;}