Question: intersection, merger, subtraction, and population
Idea: Use the leaf node of the Line Segment tree to record whether the point is covered by the interval. Because of the open interval, consider discretization and multiply the value by 2.
U: overwrite the interval [l, r] to 1.
I: overwrite [-∞, l) (r, ∞] to 0.
D: overwrite the range [l, r] to 0.
C: overwrite [-∞, l) (r, ∞] to 0, and the [l, r] range is 0/1 interchangeable.
S: [l, r] 0/1 Interchange
Interval modification is easy, but it is difficult to add intervals that are different or different.
We want to maintain such a line segment tree. If the setv of the segment is not-1 (it is-1 during initialization ), it indicates that all the values in the corresponding section of the node are setv. If the setv values of the root node and child node are not-1, we only recognize the setv value above the root node. Then, an xorv value is maintained, indicating whether the corresponding section of the node is exclusive or odd (the same or even times are the same as the same or not, and the value is 0 ). This xorv value must appear before the setv value for the first time. That is to say, a meaningful xorv value is first encountered during the search, and then a meaningful setv value is encountered, xorv = 1, or setv! =-1 ). When you want to modify a CIDR block or find a CIDR Block, the xorv and setv values are continuously pressed down with pushdown. Obviously, we can understand this nature: When an interval is overwritten, no matter whether it is different or marked before, it makes no sense. Therefore, when a node is overwritten, the exception or mark is cleared.
When a node is marked with an exception or an exception, first determine the coverage mark. If it is 0 or 1, change the coverage mark directly. Otherwise, change the exception or mark.
During output, we can use a hash array to record and use a query to compress the values on the Line Segment tree to the hash array.
Pay attention to several issues: 1. 0
2. (3, 3) the case of this empty set
# Include <cstdio> # include <cstring> # define M (L + R)> 1) # define ls (o <1) # define rs (o <1 | 1) # define lson ls, L, M # define rson rs, M + 1, Rconst int maxn = 66666*2; bool hash [maxn], empty = 1, flag = 0; int n, yl, yr, v, setv [maxn * 4], xorv [maxn * 4],, b, low = 0, high; char op, left, right; void fxor (int o) {if (setv [o]> = 0) setv [o] ^ = 1; else xorv [o] ^ = 1;} void pushdown (int o) {if (setv [o]> = 0) {setv [ls] = setv [rs] = setv [o]; xorv [ls] = xorv [rs] = 0; Setv [o] =-1;} if (xorv [o]) {fxor (ls); fxor (rs); xorv [o] = 0 ;}} void setupdate (int o, int L, int R) {if (yl <= L & R <= yr) {xorv [o] = 0; setv [o] = v; return;} pushdown (o); if (yl <= M) setupdate (lson); if (M <yr) setupdate (rson );} void xorupdate (int o, int L, int R) {if (yl <= L & R <= yr) {fxor (o); return;} pushdown (o ); if (yl <= M) xorupdate (lson); if (M <yr) xorupdate (rson);} void query (int o, int L, int R) {if (setv [o]> = 0) {if (setv [o]) for (int I = L; I <= R; ++ I) hash [I] = 1; // override the information to return;} pushdown (o ); if (yl <= M) query (lson); if (M <yr) query (rson);} void init () {memset (setv,-1, sizeof (setv); memset (hash, 0, sizeof (hash); xorv [1] = setv [1] = 0;} void read () {while (~ Scanf ("% c % d, % d % c", & op, & left, & a, & B, & right) {a = (a + 1) * 2, B = (B + 1) * 2; if (left = '(') + + a; if (right = ') -- B; if (op = 'U') {v = 1, yl = a, yr = B; if (yl <= yr) setupdate (, maxn-1 );} else if (op = 'I') {v = 0, yl = 1, yr = A-1; if (yl <= yr) setupdate (, maxn-1 ); yl = B + 1, yr = maxn-1; if (yl <= yr) setupdate (, maxn-1);} else if (op = 'D') {v = 0, yl = a, yr = B; if (yl <= yr) setupdate (, maxn-1);} else if (op = 'C') {v = 0, yl = 1, yr = A-1; if (yl <= yr) setupdate (1, 1, maxn-1); yl = B + 1, yr = maxn-1; if (yl <= yr) setupdate (1, 1, maxn-1); yl = a, yr = B; if (yl <= yr) xorupdate (, maxn-1);} else if (op = 's') {yl = a, yr = B; if (yl <= yr) xorupdate (, maxn-1) ;}} void print () {yl = 1, yr = maxn-1; query (, maxn-1 ); while (low <maxn) {while (! Hash [low] & low <maxn) + + low; high = low + 1; while (hash [high] & high <maxn) ++ high; -- high; if (low> = maxn) break; empty = 0; if (flag) printf (""); flag = 1; if (low & 1) printf ("("); else printf ("["); printf ("% d, % d", (low/2)-1, (high-1)/2 ); if (high & 1) printf (")"); else printf ("]"); low = high + 1 ;}if (empty) printf ("empty set "); puts ("") ;}int main () {init (); read (); print (); return 0 ;}