Segment tree Interval Update, interval statistics poj 2777 Count Color
Question:
Dye a board with a length of L. The Board can be divided into numbers 1, 2, 3... L segment. There are O operations in total. There are two types of operations: 1. color A to B as C 2. ask how many colors are there between A and B. The color ranges from 1 to T, and cannot exceed 30.
Idea: 1. Because there are no more than 30 colors, you can consider bitwise operations. Each digit represents a color. A 32-bit integer can store all the color states.
2. for operation 1, that is, the Interval Update operation, you need to use the lazy operation to update the subnode, color the child node to lazy (that is, the color of the last node) and move lazy down. (Pushdown function in the Code). After updating the child node, use the pushup function to update the dyeing status of the child node to the parent node.
3. for operation 2, that is, interval query, the lazy operation is also used. You need to use the pushdown function to dye the subnode and then query the target interval, return the dyeing status of the target interval (a 32-bit integer). Finally, the dyeing status of the queried interval is bitwise AND, and the number of 1 in the binary is the number of colors used.
Easy to troubleshoot:
1. Use the lazy operation. Otherwise, the operation times out.
2. During creation, you must use pushup to update the parent node.
3. In the pushup function, the dyeing status of the left and right subnodes is bitwise OR, while in the pushdown function, the color of the last Dyeing of the parent node is directly updated to the subnode. The reason is that pushup is used to combine subintervals, while pushdown is used to dye subintervals.
4. Use pushdown when querying, because the status of the queried subnode may not be updated.
5. A may be greater than B
Code:
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
Using namespace std; # define PB push_back # define MP make_pair # define REP (I, x, n) for (int I = x; I <(n); ++ I) # define FOR (I, l, h) for (int I = (l); I <= (h); ++ I) # define FORD (I, h, l) for (int I = (h); I> = (l); -- I) # define SZ (X) (int) (X ). size () # define ALL (X ). begin (), (X ). end () # define RI (X) scanf ("% d", & (X) # define RII (X, Y) scanf ("% d ", & (X), & (Y) # define RIII (X, Y, Z) scanf ("% d", & (X ), & (Y), & (Z) # define DRI (X) int (X); scanf ("% d", & X) # define DRII (X, Y) int X, Y; scanf ("% d", & X, & Y) # define DRIII (X, Y, Z) int X, Y, Z; scanf ("% d", & X, & Y, & Z) # define OI (X) printf ("% d", X ); # define RS (X) scanf ("% s", (X) # define MS0 (X) memset (X), 0, sizeof (X ))) # define MS1 (X) memset (X),-1, sizeof (X) # define LEN (X) strlen (X) # define F first # define S second # define Swap (a, B) (a ^ = B, B ^ = a, a ^ = B) # define Dpoint strcut node {int x, y} # define cmpd int cmp (const int & a, const int & B) {return a> B ;} /* # ifdef HOME freopen ("in.txt", "r", stdin); # endif */const int MOD = 1e9 + 7; typedef vector
VI; typedef vector
VS; typedef vector
VD; typedef long LL; typedef pair
PII; // # define HOMEint Scan () {int res = 0, ch, flag = 0; if (ch = getchar () = '-') // determine plus and minus flag = 1; else if (ch> = '0' & ch <= '9') // obtain the complete number res = ch-'0 '; while (ch = getchar ()> = '0' & ch <= '9') res = res * 10 + ch-'0'; return flag? -Res: res ;} /* -------------- PLEASE---DO---NOT---HACK--ME -------------------- */long int col [400000 + 10]; int num; int lazy [400000 + 10]; int l, t, o; void pushdown (int rt) {if (lazy [rt]) {lazy [rt <1] = lazy [(rt <1) + 1] = lazy [rt]; col [rt <1] = lazy [rt]; col [(rt <1) + 1] = lazy [rt]; lazy [rt] = 0 ;}} void pushup (int rt) {col [rt] = col [rt <1] | (col [(rt <1) + 1]);} void build (int l, int r, int rt) {if (l = r) {col [rt] = 1; return;} int m = (l + r)> 1; build (l, m, rt <1); build (m + 1, r, (rt <1) + 1); pushup (rt);} void update (int l, int r, int rt, int a, int B, int c) {if (a <= l & r <= B) {col [rt] = c; lazy [rt] = c; return;} pushdown (rt); int m = (l + r)> 1; if (a <= m) update (l, m, rt <1, a, B, c); if (B> m) update (m + 1, r, (rt <1) + 1, a, B, c); pushup (rt);} long int query (int l, int r, int rt, int a, int B) {if (a <= l & r <= B) {return col [rt];} pushdown (rt); int m = (l + r)> 1; long int ans = 0; if (a <= m) ans = ans | query (l, m, rt <1, a, B); if (B> m) ans = ans | query (m + 1, r, (rt <1) + 1, a, B); return ans;} int main () {cin> l> t> o; MS0 (col); MS0 (lazy); num = 0; build (1, l, 1 ); for (int I = 0; I
B) {Swap (a, B);} update (1, l, 1, a, B, 1 <(co-1 ));} else if (c = 'P') {RII (a, B); num = 0; if (a> B) Swap (a, B ); long int ans = query (1, l, 1, a, B); for (int j = 0; j