Interval query, vertex modification, insertion, and deletion. Let's take it as a template first. It's a little frustrating, supplemented, and optimized slowly.
# 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 = 700100; struct N {// info int son [2], pre; // data int sta, ls, rs, s; int w, g [2]; bool mark [2];} st [MAXN]; struct W {int sta, w;} num [200100]; void Output (int root) {if (root =-1) return; Output (st [r Oot]. son [0]); printf ("root = % d pre = % d data = % 2d lg = % 2d rg = % 2d sta = % 2d ls = % d rs = % d s = % d \ n ", root, st [root]. pre, st [root]. w, st [root]. g [0], st [root]. g [1], st [root]. sta, st [root]. ls, st [root]. rs, st [root]. s); Output (st [root]. son [1]);} int Top; int Gcd (int a, int B) {int t; while (B) {t = a; a = B; B = t % B;} return a;} // update the data domain void Updata (int root) {st [root] of st [root]. ls = 0, st [root]. rs = 0; st [root ]. G [st [root]. sta] = st [root]. w; st [root]. g [1 ^ st [root]. sta] = 1; st [root]. mark [st [root]. sta] = true; st [root]. mark [1 ^ st [root]. sta] = false; if (st [root]. son [0]! =-1) {if (st [root]. mark [0] = true) st [root]. g [0] = (st [st [root]. son [0]. mark [0]? Gcd (st [root]. g [0], st [st [root]. son [0]. g [0]): st [root]. g [0]); else st [root]. g [0] = st [st [root]. son [0]. g [0]; if (st [root]. mark [1] = true) st [root]. g [1] = (st [st [root]. son [0]. mark [1]? Gcd (st [root]. g [1], st [st [root]. son [0]. g [1]): st [root]. g [1]); else st [root]. g [1] = st [st [root]. son [0]. g [1]; st [root]. mark [0] = (st [root]. mark [0] | st [st [root]. son [0]. mark [0]); st [root]. mark [1] = (st [root]. mark [1] | st [st [root]. son [0]. mark [1]); st [root]. ls = st [st [root]. son [0]. s;} if (st [root]. son [1]! =-1) {if (st [root]. mark [0] = true) st [root]. g [0] = (st [st [root]. son [1]. mark [0]? Gcd (st [root]. g [0], st [st [root]. son [1]. g [0]): st [root]. g [0]); else st [root]. g [0] = st [st [root]. son [1]. g [0]; if (st [root]. mark [1] = true) st [root]. g [1] = (st [st [root]. son [1]. mark [1]? Gcd (st [root]. g [1], st [st [root]. son [1]. g [1]): st [root]. g [1]); else st [root]. g [1] = st [st [root]. son [1]. g [1]; st [root]. mark [0] = (st [root]. mark [0] | st [st [root]. son [1]. mark [0]); st [root]. mark [1] = (st [root]. mark [1] | st [st [root]. son [1]. mark [1]); st [root]. rs = 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]. w = num [mid]. w; st [root]. sta = num [mid]. sta; st [root]. pre = pre; st [root]. son [0] = st [root]. son [1] =-1; Init (st [root]. son [0], s, mid-1, root); Init (st [root]. son [1], mid + 1, e, root); Updata (root);} // dir = 0, root is the left son of pre, dir = 1 is the right son. Void Rotate (int root, int dir) {// Rotate 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; // update the data domain Updata (temp); Updata (root) ;}// rotate root to goal, when goal = 0, it means to rotate the root node to the root node location. Int Splay (int root, int 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) {while (st [root]. ls + 1! = Site) {if (st [root]. ls + 1 <site) {site = site-st [root]. ls-1; root = st [root]. son [1];} else {root = st [root]. son [0] ;}}return root;} void Increase (int root, int site, int w, int sta, int & R) {root = Search_Site (root, site ); R = Splay (root, 0); // insert a vertex int tr = st [R] to the far left of the right subtree of the root node. son [1]; st [R]. son [1] =-1; int New = Top ++; st [New]. w = w; st [New]. sta = sta; st [New]. pre = 0; st [0]. son [0] = New; st [R]. pre = New; st [New]. son [0] = R; st [tr]. pre = New; st [New]. son [1] = tr; Updata (R); Updata (New); R = New;} void Link (int & root, int tr, int pre) {if (root =-1) {root = tr; st [root]. pre = pre;} else {Link (st [root]. son [1], tr, root);} Updata (root);} // if no node is deleted, void Decrease (int root, int site, int & R) {root = Search_Site (root, site); // Output (R); // printf ("D site = % d root = % d R = % d \ n ", site, root, R); R = Splay (root, 0); // Delete the root node R = st [root]. son [0]; st [R]. pre = st [root]. pre; st [0]. son [0] = R; int tr = st [root]. son [1]; // connect tr to the rightmost side of R. Link (R, tr, root); Updata (R);} void Reinit (int root, int site, int & R) {root = Search_Site (root, site ); R = Splay (root, 0); st [R]. sta ^ = 1; Updata (R);} void Modify (int root, int site, int w, int & R) {root = Search_Site (root, site ); R = Splay (root, 0); st [R]. w = w; Updata (R);} int Query (int root, int l, int r, int sta, int & R) {int lsite = Search_Site (root, l ); int rsite = Search_Site (root, r); R = Splay (rsite, 0); R = Splay (lsite, 0); if (st [st [R]. son [1]. son [0] =-1 | st [st [R]. son [1]. son [0]. mark [sta] = false) return-1; return st [st [R]. son [1]. son [0]. g [sta];} int main () {// freopen ("data.txt", "r", stdin); // freopen ("dataout.txt", "w ", stdout); int n, m; int I; int root; while (scanf ("% d", & n, & m )! = EOF) {for (I = 2; I <= n + 1; ++ I) {scanf ("% d", & num [I]. w, & num [I]. sta);} // cout <