Question: give n a line point and M operations. D x destroys the village X, q x queries the number of villages directly and indirectly connected to the village X (including its own), and r restores the first village damaged.
In addition to the following method, another method is used to update the Left and Right endpoints of the queried range during the query.
/* After the code style is updated */# include <iostream> # include <cstdio> # include <cstring> # include <stack> using namespace STD; # define LL (X) (x <1) # define RR (x) (x <1 | 1) # define mid (a, B) (a + (B-a)> 1) const int n = 50005; struct node {int LFT, rht; int lmx, RMX; int Len () {return rht-LFT + 1;} int mid () {return mid (LFT, rht);} void Init () {lmx = RMX = Len ();} void fun (INT valu) {If (valu =-1) lmx = RMX = 0; else lmx = RMX = 1 ;}}; int n, m; struct segtree {Node Tree [N * 4]; void up (int ind) {tree [ind]. lmx = tree [LL (IND)]. lmx; tree [ind]. RMX = tree [RR (IND)]. RMX; If (tree [LL (IND)]. lmx = tree [LL (IND)]. len () tree [ind]. lmx + = tree [RR (IND)]. lmx; If (tree [RR (IND)]. RMX = tree [RR (IND)]. len () tree [ind]. RMX + = tree [LL (IND)]. RMX;} void build (int lft, int rht, int IND) {tree [ind]. LFT = LFT, tree [ind]. rht = rht; tree [ind]. init (); If (LFT! = RHT) {int mid = tree [ind]. mid (); Build (LFT, mid, LL (IND); Build (Mid + 1, rht, RR (IND) ;}} void updata (INT POs, int ind, int valu) {If (tree [ind]. LFT = tree [ind]. RHT) tree [ind]. fun (valu); else {int mid = tree [ind]. mid (); If (Pos <= mid) updata (Pos, LL (IND), valu); else updata (Pos, RR (IND), valu ); up (IND) ;}} void query (INT POs, int ind, Int & X, Int & Y) {If (tree [ind]. LFT = tree [ind]. RHT) {If (tree [ind]. lmx = 1) x = y = tree [ind]. LFT; else x = y = 0;} else {int mid = tree [ind]. mid (); If (Pos <= mid) query (Pos, LL (IND), x, y); else query (Pos, RR (IND), x, y ); if (tree [LL (IND)]. rht = y) Y + = tree [RR (IND)]. lmx; If (tree [RR (IND)]. LFT = x) x-= tree [LL (IND)]. RMX ;}} seg; int main () {While (scanf ("% d", & N, & M )! = EOF) {stack <int> q; seg. build (1, n, 1); While (M --) {char cmd [5]; int POs, St, Ed; scanf ("% s", CMD ); if (CMD [0] = 'D') {scanf ("% d", & Pos); seg. updata (Pos, 1,-1); q. push (POS);} else if (CMD [0] = 'q') {scanf ("% d", & Pos); seg. query (Pos, 1, St, Ed); If (ST = 0 & ED = 0) puts ("0 "); else printf ("% d \ n", Ed-ST + 1); // cout <st <"" <ED <Endl;} else {seg. updata (Q. top (), 1, 1); q. pop () ;}} return 0 ;}
I didn't say there were multiple groups of data, but there were multiple groups of data, so I was dizzy. Similar to the question of hotel, you must check whether the query is in the continuous range of the left and right endpoints of the parent interval, then, check whether the connection is in the left and right subintervals. Instead of querying whether it is within the continuous range of the Left endpoint of the Left subinterval, an error occurs. This is because the continuous range of the parent interval exceeds the midpoint.
/* Before code style update */# include <iostream> # include <cstdio> # include <stack> using namespace STD; const int n = 50005; struct node {int left, right; int Lmax, rmax; int mid () {return left + (right-left)/2;} int DIS () {return right-left + 1 ;}}; struct segtree {node tree [N * 4]; void build (INT left, int right, int R) {tree [R]. left = left; tree [R]. right = right; tree [R]. lmax = tree [R]. rmax = tree [R]. DIS (); If (left <right) {int mid = tree [R]. Mid (); Build (left, mid, R * 2); Build (Mid + 1, right, R * 2 + 1) ;}} void updata (INT POs, int R, int Co) {If (tree [R]. left = tree [R]. right) tree [R]. lmax = tree [R]. rmax = Co; else {int mid = tree [R]. mid (); If (Pos <= mid) updata (Pos, R * 2, CO); else if (Pos> mid) updata (Pos, R * 2 + 1, CO); tree [R]. lmax = tree [R * 2]. lmax; tree [R]. rmax = tree [R * 2 + 1]. rmax; If (tree [R * 2]. lmax = tree [R * 2]. DIS () tree [R]. lmax + = tree [R * 2 + 1]. lmax; If (tree [R * 2 + 1 ]. Rmax = tree [R * 2 + 1]. DIS () tree [R]. rmax + = tree [R * 2]. rmax ;}} int query (INT POs, int R) {If (tree [R]. left = tree [R]. right) return tree [R]. lmax; else {int mid = tree [R]. mid (); If (tree [R]. lmax + tree [R]. left> POS) return tree [R]. lmax; else if (tree [R * 2 + 1]. lmax + tree [R * 2 + 1]. left> POS & tree [R * 2]. right-tree [R * 2]. rmax <POS) return tree [R * 2]. rmax + tree [R * 2 + 1]. lmax; else if (tree [R]. right-tree [R]. rmax <POS) return tree [R]. rmax; else if (Pos <= mid) return query (Pos, R * 2); else return query (Pos, R * 2 + 1) ;}} seg; int main () {int n, m; while (scanf ("% d", & N, & M )! = EOF) {stack <int> q; seg. build (1, n, 1); For (INT I = 0; I <m; I ++) {int A; char cmd [5]; scanf ("% s", CMD); If (CMD [0] = 'D') {scanf ("% d", & A); seg. updata (A, 1, 0); q. push (a);} else if (CMD [0] = 'q') {scanf ("% d", & A); printf ("% d \ n ", SEG. query (A, 1);} else {seg. updata (Q. top (), 1, 1); q. pop () ;}} return 0 ;}