POJ 2777 Count Color(线段树+懒惰标记)
2017-08-14 20:35
330 查看
Description
Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem.There is a very long board with length L centimeter, L is a positive integer, so we can evenly divide the board into L segments, and they are labeled by 1, 2, … L from left to right, each is 1 centimeter long. Now we have to color the board - one segment with only one color. We can do following two operations on the board:
“C A B C” Color the board from segment A to segment B with color C.
“P A B” Output the number of different colors painted between segment A and segment B (including).
In our daily life, we have very few words to describe a color (red, green, blue, yellow…), so you may assume that the total 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 was painted in color 1. Now the rest of problem is left to your.
Input
First line of input contains L (1 <= L <= 100000), T (1 <= T <= 30) 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 are integers, and A may be larger than B) as an operation defined previously.Output
Ouput results of the output operation in order, each line contains a number.Sample Input
2 2 4 C 1 1 2 P 1 2 C 2 2 2 P 1 2
Sample Output
2 1
题目大意
C A B C 代表将区间[A,B]染成颜色C,P A B 代表查询区间[A,B]有多少种颜色,初始状态下所有的节点颜色为1。解题思路
类似于2558,只是在建树时将每一个节点的颜色初始化为1。代码实现
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define maxn 100007 int color[maxn<<4]; bool vis[35]; int ans; void build(int l,int r,int rt) { color[rt]=1; if(l==r) return ; int m=(l+r)/2; build(l,m,rt<<1); build(m+1,r,rt<<1|1); } void PushDown(int rt) { color[rt<<1]=color[rt<<1|1]=color[rt]; color[rt]=-1; } void Update(int L,int R,int c,int l,int r,int rt) { if(L<=l&&R>=r) { color[rt]=c; return ; } //如果[L,R]与当前区间有交集,则将其标记下推,这样在查询时,只要遇到color[rt]!=-1, //则其下面的区间全部为一种颜色,直接统计ans++就可以返回了 if(color[rt]!=-1) PushDown(rt); int m=(l+r)/2; if(m>=L) Update(L,R,c,l,m,rt<<1); if(m<R) Update(L,R,c,m+1,r,rt<<1|1); } void Query(int L,int R,int l,int r,int rt) { if(color[rt]!=-1) { if(!vis[color[rt]]) { ans++; vis[color[rt]]=1; } return ; } if(l==r) return; int m=(l+r)/2; if(m>=L) Query(L,R,l,m,rt<<1); if(m<R) Query(L,R,m+1,r,rt<<1|1); } int main() { int L,T,O; char ch; int s,e,c; while(~scanf("%d %d %d%*c",&L,&T,&O)) { build(1,L,1); while(O--) { scanf("%c",&ch); if(ch=='C') { scanf("%d %d %d%*c",&s,&e,&c); if(s>e) swap(s,e); Update(s,e,c,1,L,1); } else { scanf("%d %d%*c",&s,&e); if(s>e) swap(s,e); ans=0; memset(vis,0,sizeof(vis)); Query(s,e,1,L,1); printf("%d\n",ans); } } } return 0; }
相关文章推荐
- poj 2777 Count Color
- POJ 2777 Count Color
- POJ - 2777 Count Color(线段树 成段更新 区间查询)
- POJ 2777 Count Color
- poj 2777 Count Color
- poj 2777 Count Color (线段树区间更新)
- poj 2777 Count Color
- POJ 2777 Count Color (线段树区间更新 位压缩)
- POJ 2777 Count Color (线段树+位运算)
- POJ 2777 Count Color(线段树区间更新)
- POJ 2777 Count Color (二进制或 线段树)
- POJ2777——Count Color(线段树)
- POJ 2777 Count Color 线段树入门题
- POJ 2777 Count Color (线段树、lazy思想)
- poj 2777 Count Color
- POJ 2777 Count Color (线段树区间更新)
- Poj 2777 Count Color
- POJ 2777 Count Color(线段树+位运算)
- POJ--2777--Count Color
- poj 2777 Count Color(线段树区区+染色问题)