Count Color
Time Limit: 1000MS |
|
Memory Limit: 65536K |
Total Submissions: 41202 |
|
Accepted: 12458 |
Description
Chosen Problem solving and program design as a optional course, you is required to solve all kinds of problems. Here, we get a new problem.
There is a very long board with length L centimeter, L was a positive integer, so we can evenly divide the board into L seg ments, and they is labeled by 1, 2, ... L from left to right, each is 1 centimeter long. Now we has to color the Board-one segment with only one color. We can do following-operations on the board:
1. "C A B C" Color the board from segment A to segment B with Color C.
2. "P A B" Output the number of different colors painted between segment A and segment B (including).
In our daily life, we had very few words to describe a color (red, green, blue, yellow ...), so if you could assume that the Tota L number of different colors T is very small. To make it simple, we express the names of colors as color 1, color 2, ... color T. At the beginning, the board is painted in color 1. Now the rest of problem are left to your.
Input
First line of input contains L (1 <= L <= 100000), T (1 <= t <=) and O (1 <= O <= 100000). Here O denotes the number of operations. Following O lines, each contains "c a b C" or "P a B" (here A, B, C is integers, and A may is larger than B) as an Operat Ion defined previously.
Output
Ouput results of the output operation in order, each line contains a number.
Sample Input
2 2 4C 1 1 2P 1 2C 2 2 2P 1 2
Sample Output
21st
Topic meaning: To three numbers n,t,m n represents the interval size, T represents the kind of the color (no use) m represents the update interval value for the number of times the operation is ' C ', and the operation for ' Q ' represents the number of colors in the asking interval and outputs.
Lazy thought and bit arithmetic are used. Look at the code that someone else's mind is calling out. It's really useful to understand the line tree.
Lazy: As long as the inserted interval is completely covered by the current node, the managed interval is no longer down, a lazy flag is played on the current node, and then returned directly.
The next time you encounter a lazy tag with the current node, pass it directly to the two sons, emptying their own tags. The advantage is that you don't have to update to the child nodes when you meet the conditions, saving time.
Bit operations: Using binary to represent each bit of the color (can think of people really know the algorithm,, slag worship) such as the left leaf node is dyed 3, the right is dyed 4
The father's node was dyed by two colors. 00...0100 | 00...1000 = 00...1100 Indicates that this interval has been dyed by 3 and 4, the color of which is up to 30, so it can be expressed in int
For more explanations, see the code below:
#include <stdio.h>#include<algorithm>#include<string.h>#include<iostream>#define N1100005using namespace std;Const intMAXSIZE = 100005;intsum;struct tree{intColor///binary representation of 30 colors, so the bit or result of every two sub-range is the Father node . intCover;///Indicates whether the color of an interval is the same intL,r;} Tree[maxsize<<2];voidPushup (inti) {Tree[i].color= Tree[i<<1].color|tree[i<<1|1].color;}voidPushdown (inti) { if(tree[i].cover==1) {Tree[i<<1].color =Tree[i].color; Tree[i<<1|1].color =Tree[i].color; Tree[i<<1].cover = Tree[i<<1|1].cover = 1; Tree[i].cover= 0; }}voidBuildintLintRintidx) {TREE[IDX].L=l; TREE[IDX].R=R; Tree[idx].color= 1;///Just start with a color of 1Tree[idx].cover = 1;///First interval color is the same if(L==R)return ; intMid = (l+r) >>1; Build (L,mid,idx<<1); Build (Mid+1,r,idx<<1|1); Pushup (idx);}voidUpdateintLintRintIdxintval) { if(tree[idx].l>=l&&r>=TREE[IDX].R) {Tree[idx].cover= 1; Tree[idx].color=Val; return; } pushdown (IDX); intMid = (TREE[IDX].L+TREE[IDX].R) >>1; if(r<=mid) Update (l,r,idx<<1, Val); Else if(l>mid) Update (l,r,idx<<1|1, Val); Else{update (L,mid,idx<<1, Val); Update (Mid+1,r,idx<<1|1, Val); } pushup (idx);}voidQueryintLintRintidx) { if(tree[idx].l>=l&&tree[idx].r<=R) { //printf ("Tree[%d].color =%d\n", idx,tree[idx].color);sum|=Tree[idx].color; return; } if(tree[idx].cover==1) {///The interval color is the same no need to be divided downsum|=Tree[idx].color; return; } intMid = (TREE[IDX].L+TREE[IDX].R) >>1; if(r<=mid) query (l,r,idx<<1); Else if(l>mid) query (l,r,idx<<1|1); Else{query (L,mid,idx<<1); Query (Mid+1,r,idx<<1|1); }}intsolve () {intAns = 0; //printf ("sum =%d\n", sum); while(sum) {if(sum&1)///If the lowest bit of sum is 1 the proof has been dyedans++; Sum= Sum>>1; } returnans;}intMain () {intn,t,m; while(scanf ("%d%d%d", &n,&t,&m)! =EOF) {Build (1,n,1); while(m--){ CharS[5]; scanf ('%s ', s); if(s[0]== ' C '){ intA,b,c; scanf ("%d%d%d",&a,&b,&c); Update (A, B,1,1<< (c-1));///binary to represent the color, such as dyeing into 2 binary is 00. 010 that is 2^1 (^ represents the second party)}Else{ intb; Sum= 0; scanf ("%d%d",&a,&b); Query (A, B,1); printf ("%d\n", Solve ()); } } } return0;}
Pku 2777 (classic segment tree dyeing problem)