The latency mark is like a line segment tree.
After the tree is stretched in place, the interval inversion becomes a simple recursive exchange between the left and right sons.
The stretching tree is more and more beautiful, And the stretching operation is tempting. In short, the data structure is too attractive.
It is relatively simple, so you can directly launch the template.
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Pragma comment (linker, "/STACK: 1024000000"); # define EPS (1e-8) # define LL long # define ULL unsigned long # define _ LL _ int64 # define _ INF 0x3f3f3f3f # define Mod 9999991 using namespace std; const int MAXN = 100100; struct N {// info int son [2], pre, data; // data bool mark; int ls, rs, s;} st [MAXN]; int Top; struct W {int data, site;} num [MAXN], tnum [MAXN]; bool cmp (W a1, W a2) {if (a1.data <a2.data) return True; if (a1.data = a2.data & a1.site <a2.site) return true; return false;} void Push_Down (int root) {if (st [root]. mark = 1) {st [root]. mark = 0; if (st [root]. son [0]! =-1) st [st [root]. son [0]. mark ^ = 1; if (st [root]. son [1]! =-1) st [st [root]. son [1]. mark ^ = 1; int temp; temp = st [root]. son [0]; st [root]. son [0] = st [root]. son [1]; st [root]. son [1] = temp; temp = st [root]. ls; st [root]. ls = st [root]. rs; st [root]. rs = temp ;}} void Updata (int root) {st [root]. ls = st [root]. son [0] =-1? 0: st [st [root]. son [0]. s; st [root]. rs = st [root]. son [1] =-1? 0: st [st [root]. son [1]. s; st [root]. s = st [root]. ls + st [root]. rs + 1;} void Init (int & root, int s, int e, int pre) {if (s> e) return; int mid = (s + e)> 1; root = Top ++; st [root]. son [0] =-1; st [root]. son [1] =-1; st [root]. pre = pre; st [root]. data = num [mid]. data; st [root]. mark = 0; num [mid]. site = root; Init (st [root]. son [0], s, mid-1, root); Init (st [root]. son [1], mid + 1, e, root); Updata (root);} void Rotate (Int root, int dir) {st [st [root]. pre]. son [dir] = st [root]. son [1 ^ dir]; st [root]. son [1 ^ dir] = st [root]. pre; if (st [st [st [root]. pre]. pre]. son [0] = st [root]. pre) st [st [st [root]. pre]. pre]. son [0] = root; else st [st [st [root]. pre]. pre]. son [1] = root; int temp = st [root]. pre; st [root]. pre = st [st [root]. pre]. pre; st [temp]. pre = root; if (st [temp]. son [dir]! =-1) st [st [temp]. son [dir]. pre = temp; Updata (temp); Updata (root);} void Updata_Lazy (int root, int goal) {if (st [root]. pre! = Goal) {Updata_Lazy (st [root]. pre, goal);} Push_Down (root);} int Splay (int root, int goal) {Updata_Lazy (root, goal); while (st [root]. pre! = Goal) {Rotate (root, (st [st [root]. pre]. son [0] = root? 0: 1);} return root;} int Search_Site (int root, int site) {do {Push_Down (root); if (st [root]. ls + 1 = site) return root; if (st [root]. ls + 1 <site) {site = site-st [root]. ls-1; root = st [root]. son [1];} else root = st [root]. son [0];} while (1);} int main () {int n; int I; int root, lsite, rsite; while (scanf ("% d ", & n) {for (I = 2; I <= n + 1; ++ I) {scanf ("% d", & tnum [I]. data); num [I]. site = I; tnum [I]. site = I;} sort (tnum + 2, tnum + n + 2, cmp); num [1]. data = 1, num [1]. site = 1; num [n + 2]. data = n + 2, num [n + 2]. site = n + 2; for (I = 2; I <= n + 1; ++ I) {num [tnum [I]. site]. data = I;} root =-1, Top = 1; Init (root, 1, n + 2, 0); st [0]. son [0] = root, st [0]. son [1] =-1; // virtual parent node for (I = 2; I <= n + 1; ++ I) {root = Splay (num [tnum [I]. site]. site, 0); printf ("% d", st [root]. ls); if (I = n + 1) printf ("\ n"); else printf (""); lsite = min (st [root]. ls + 1, num [tnum [I]. site]. data)-1; rsite = max (st [root]. ls + 1, num [tnum [I]. site]. data) + 1; lsite = Search_Site (root, lsite); rsite = Search_Site (root, rsite); root = Splay (rsite, 0); root = Splay (lsite, 0); st [st [st [root]. son [1]. son [0]. mark ^ = 1 ;}} return 0 ;}