Question:
Calculates the number of monotonically dropped tuples. The three elements do not have to be continuous.
Ideas:
Convert to double reverse order:
The line segment tree calculates the reverse order number, and then the reverse order number of the reverse order number sequence.
# Include <cstdio> # include <algorithm> using namespace std; # define lson l, m, rt <1 # define rson m + 1, r, rt <1 | 1 typedef long ll; const int maxn = 1000005; ll sum [maxn <2]; typedef struct stru {int id; int val;} stru; stru x [maxn]; int rev [maxn]; bool cmpid (stru a, stru B) {return. id <B. id;} bool cmpval (stru a, stru B) {return. val <B. val;} void PushUP (int rt) {sum [rt] = sum [rt <1] + sum [rt <<1 | 1];} void build (int l, int r, int rt) {sum [rt] = 0; if (l = r) return; int m = (l + r)> 1; build (lson); build (rson);} void update (int p, int l, int r, int rt) {if (l = r) {sum [rt] ++; return;} // The update method is to add 1 to position p, therefore, 1 int m = (l + r)> 1 is added to the upstream node. if (p <= m) update (p, lson); else update (p, rson); PushUP (rt);} void updaterev (int id, int p, int l, int r, int rt) {if (l = r) {sum [rt] = rev [id]; // print F ("x [% d] % d rev [% d] % I64d \ n", id, x [id], id, rev [id]); return ;} // The update method is to add 1 to the p position, so 1 int m = (l + r)> 1 to the upward node; if (p <= m) updaterev (id, p, lson); else updaterev (id, p, rson); PushUP (rt);} ll query (int L, int R, int l, int r, int rt) {if (L <= l & r <= R) {return sum [rt];} int m = (l + r)> 1; ll ret = 0; if (L <= m) ret + = query (L, R, lson); if (R> m) ret + = query (L, R, rson); return ret;} I Nt main () {int n; scanf ("% d", & n); for (int I = 0; I <n; I ++) {scanf ("% d", & x [I]. val); x [I]. id = I;} sort (x, x + n, cmpval); for (int I = 0; I <n; I ++) x [I]. val = I; sort (x, x + n, cmpid); build (0, n-1, 1); for (int I = 0; I <n; I ++) {// algorithm: inserts elements into the line segment tree in sequence, the reverse logarithm of each number is the number of inserted numbers greater than it. rev [I] = query (x [I]. val + 1, n-1, 0, n-1, 1); // the reverse order of each number update (x [I]. val, 0, n-1, 1) ;}/// the sum of the reverse orders of numbers greater than x [I] is required !!! Ll ans = 0; build (0, n-1, 1); for (int I = 0; I <n; I ++) {ans + = query (x [I]. val + 1, n-1, 0, n-1, 1); // updaterev (I, x [I]. val, 0, n-1, 1);} printf ("% I64d \ n", ans); return 0 ;}