Title Link: BZOJ-2212
Problem analysis
In the sub-tree x, the number of reverse order is: x Shone reverse of the number + X right sub-tree in reverse order number + cross x Zuozi and right subtree in reverse order.
The inverse of the left and right sub-tree is independent of whether or not the exchange of the left and the sub-tree, whether the exchange of the left and the sub-tree depends on the exchange "across the X Zuozi and in reverse order" will decrease.
So we asked for two cases of the logarithm of the reverse order, using a segment tree merge, each node to build a tree segment, and then merge at the same time to find out two cases of reverse pairs.
Code
#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath > #include <algorithm>using namespace std;inline void Read (int &num) {char c = getchar (); while (C < ' 0 ' | | c > ' 9 ') c = GetChar (); Num = C-' 0 '; c = GetChar (); while (c >= ' 0 ' && C <= ' 9 ') {num = num * + C-' 0 '; c = GetChar ();}} typedef long LONG Ll;inline ll Gmin (ll A, ll b) {return a < b? A:b;} const int MAXN = 400000 + 5, Maxnode = 4000000 + 5;int N, Indext, Index, Rt;int A[MAXN], tree[maxn][2], ROOT[MAXN], T[MAXN ODE], son[maxnode][2]; LL Ans0, Ans1, ans;void read_tree (int &x) {x = ++indext; Read (a[x]); if (a[x]! = 0) return; Read_tree (Tree[x][0]); Read_tree (tree[x][1]);} inline void Update (int x) {t[x] = T[son[x][0]] + t[son[x][1];} void Insert (int &x, int s, int t, int Pos) {if (x = = 0) x = ++index;if (s = = t) {t[x] = 1;return;} int m = (s + t) >> 1;if (pos <= m) insert (Son[x][0], S, M, Pos); else insert (son[x][1], M + 1, T, Pos); Update (x);} int Merge (int x, int y) {if (!x) return y;if (!y) return x; Ans0 + = (ll) t[son[x][1]] * (LL) t[son[y][0]]; Ans1 + = (ll) t[son[x][0]] * (LL) t[son[y][1]]; Son[x][0] = Merge (son[x][0], son[y][0]); SON[X][1] = Merge (son[x][1], son[y][1]); Update (x); return x;} void Solve (int x) {if (a[x]) return; Solve (Tree[x][0]); Solve (tree[x][1]); ANS0 = Ans1 = 0; ROOT[X] = Merge (Root[tree[x][0]], root[tree[x][1]); Ans + = Gmin (Ans0, Ans1);} int main () {scanf ("%d", &n); Read_tree (RT); for (int i = 1; I <= indext; ++i) if (a[i]! = 0) Insert (root[i], 1, N, A[i]); Solve (RT); cout << Ans << endl;return 0;}
[Bzoj 2212] [Poi2011] Tree rotations "segment tree merge"