Algorithmic Race Primer Classic p197
Main topic:
There are N table tennis enthusiasts living on a street. Often play a game of skill. Each person has a different skill value a[i]. Each match requires 3 persons: two players, one referee. They have a strange agreement that the referee must live between two players, and the referee's capacity must be between two players. Ask how many kinds of games can be organized altogether.
Analysis:
If A[1] to a[i-1] The number of small a[i] is p[i]. A[I+1] to A[n] small a[i] The number of s[i];
The number of games that can be organized when I is a referee is: p[i]* (N-i-s[i]) + (I-1-p[i]) *s[i];
The total number of matches is:
Ans = 0;for I, 1 to n (i means select I personal as referee) ans + = p[i]* (N-i-s[i]) + (I-1-p[i]) *s[i];
first determine the value of p[i], so that x[j] indicates whether there is a number of skill values of J in all A[i] that have been considered so far; (x[j] = 0 means not present, x[j] = 1 means present)
Memsest (x, 0, sizeof (x));(x is initialized to 0), and for-I, 1 to cur (cur is the current position considered, that is, the selected referee position) X[a[i]] = 1;
Then there is p[cur] = x[1]+x[2]+.....+x[a[cur]-1];
Cases:
If n = 4 A[1] = 2, a[2] = 3, a[3] = 5, a[4] = 1;
Select cur= 3,a[cur] = 5; (The third person to be a referee)
P[3] = X[1]+x[2]+x[3]+x[4] = 0 + 1 + 1 + 0 = 2; (here x[1] = 0 reason is not running to 4th)
Constant record summation, of course, is no problem (time overhead is very large)
For I, 1 to N; X[a[i]] = 1; P[i] = 0; For J, 1 to A[i]-1 p[i] + = X[j]
Modifying a single element and seeking a prefix and a standard use of a tree array can significantly reduce time (time complexity from O (NR) to O (nlogr));
For i-> 1 to n Add (A[i], 1);//(Point change) p[i] = SUM (a[i]-1);//(prefix and);
The result is basically able to find out here, that s[i]? Similar to. Direction from I--1 to n changed to I--n todown 1 can be;
The code is as follows:
#include <iostream> #include <cstdio> #include <cstring>using namespace std;const int maxn = 20000+10; const int MAXM = 100000+10;int C[MAXM], A[MAXN], P[MAXN], S[MAXN], n;inline int lowbit (int x) {return x&-x;} void Add (int x, int d) {while (x <= maxm) {//must note here is MAXM, reason can think about; C[X] + = D; x + = Lowbit (x); }}int sum (int x) {int ret = 0; while (x > 0) {ret + = c[x]; x-= Lowbit (x); } return ret;} int main () {int T; scanf ("%d", &t); while (t--) {scanf ("%d", &n); for (int i = 1; I <= n; ++i) scanf ("%d", &a[i]); memset (c, 0, sizeof (c)); for (int i = 1; I <= n; ++i) {Add (A[i], 1); P[i] = SUM (a[i]-1); } memset (c, 0, sizeof (c)); for (int i = n; i > 0; i) {Add (A[i], 1); S[i] = SUM (a[i]-1); } long long ans = 0; for (int i = 1; I <= n; ++i) {ans + p[i]* (n-i-s[i]) + (I-1-p[i]) *s[i]; } printf ("%lld\n", ans); } return 0;}
LA 4329 (tree-like array)