// I think it is quite complicated... I didn't want to send it... worship HDU's HH God ox 0, 0
/* Question: interval operation, intersection, and population: perform operations one by one to analyze: (0 and 1 indicate whether the interval is included, -1 indicates that the range contains and does not contain U: overwrites [L, R] To 1i: overwrites [-∞, L) (R, ∞] overwrite to 0d: overwrite [L, R] To 0C: overwrite [-∞, L) (R, ∞] to 0, and [L, r] range 0/1 swap S: [L, R] range 0/1 swap to segment cover the operation is very simple, more special is the interval 0/1 swap this operation, we can call it an exclusive or operation. We can clearly understand this nature: When a range is overwritten, no matter whether there is a difference or a mark before it makes no sense, so when a node gets the coverage mark, the exception or mark is cleared, and when a node gets the exception or mark, the overwriting mark is first judged, if the value is 0 or 1, change the overwrite mark directly. Otherwise, change the XOR or mark the open and closed intervals as long as the number is multiplied by 2. (an even number indicates the endpoint and an odd number indicates the interval between two vertices) */# include <cstdio> # include <cstdlib> # define maxn 2 00000 # define lson L, M, RT <1 # define rson m + 1, R, RT <1 | 1 using namespace STD; int hash [maxn]; int cover [maxn <2]; // overwrite the flag int covxor [maxn <2]; // exclusive or mark void fxor (int rt) {If (cover [RT]! =-1) cover [RT] ^ = 1; // first, determine whether the overwrite flag is 0 or 1, and else covxor [RT] ^ = 1; // I cannot understand it here. if it is not overwritten, the difference or mark is changed ???????} Void Pushdown (int rt) {// you need to update the overwrite flag. and/or flag. If (cover [RT]! =-1) {cover [RT <1] = cover [RT <1 | 1] = cover [RT]; covxor [RT <1] = covxor [RT <1 | 1] = covxor [RT]; cover [RT] =-1;} If (covxor [RT]) {fxor (RT <1); fxor (RT <1 | 1); covxor [RT] = 0 ;}} void Update (char op, int L, int R, int L, int R, int RT) {If (L> = L & R <= r) {If (OP = 'U ') {cover [RT] = 1; covxor [RT] = 0; // clear the exception or mark after a node is overwritten} If (OP = 'D ') {cover [RT] = 0; covxor [RT] = 0;} If (OP = 's' | op = 'C') {fxor (RT );} return;} Pushdown (RT); int M = (L + r)> 1; if (L <= m) {Update (OP, L, R, lson );} else if (OP = 'I' | op = 'C') {covxor [RT <1] = cover [RT <1] = 0 ;} if (M <r) {Update (OP, L, R, rson);} else if (OP = 'I' | op = 'C ') {covxor [RT <1 | 1] = cover [RT <1 | 1] = 0 ;}} void query (int l, int R, int RT) {If (cover [RT] = 1) {for (INT I = L; I <= r; I ++) hash [I] = true; return ;} else if (cover [RT] = 0) return; If (L = r) return; Pushdown (RT); int M = (L + r)> 1; query (lson); query (rson);} int Main () {char op, L, R; int A, B; covxor [1] = cover [1] = 0; while (~ Scanf ("% C % d, % d % C \ n", & OP, & L, & A, & B, & R )) {A <= 1; B <= 1; if (L = '(') A ++; If (r = ') B --; if (A> B) {If (OP = 'C' | op = 'I') {cover [l] = covxor [l] = 0 ;}} else Update (OP, A, B, 0, maxn, 1); // printf ("flag \ n");} query (0, maxn, 1 ); // hash int F1 =-1, F2; bool flag = false; For (INT I = 0; I <maxn; I ++) {If (hash [I]) {If (F1 =-1) {F1 = I;} F2 = I;} else {If (F1! =-1) {If (FLAG) printf (""); flag = true; printf ("% C % d, % d % C", F1 & 1? '(': '[', F1> 1, (F2 + 1)> 1, F2 & 1? ')': ']'); F1 =-1 ;}} if (! Flag) printf ("empty set"); puts (""); Return 0 ;}