Count Color
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 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 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 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 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 Source |
题意:
有一个board,初始都为颜色1,有两个操作,C将区间[l,r]都涂成颜色val,P询问区间[l,r]的颜色种数。
思路:
线段树区间更新,维护一个区间的颜色种类数就行了,由于只有30种颜色,可以考虑位操作,用一个int来表示。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define maxn 100005 #define lson (rt<<1) #define rson (rt<<1|1) #define INF 0x3f3f3f3f typedef long long ll; using namespace std; int n,m,tot; char s[10]; int vis[maxn<<2],sum[maxn<<2]; void pushdown(int le,int ri,int rt) { if(vis[rt]!=-1) { vis[lson]=vis[rson]=vis[rt]; sum[lson]=sum[rson]=(1<<vis[rt]); vis[rt]=-1; } } void pushup(int le,int ri,int rt) { sum[rt]=sum[lson]|sum[rson]; } void update(int le,int ri,int rt,int u,int v,int val) { if(le==u&&ri==v) { vis[rt]=val; sum[rt]=(1<<val); return ; } pushdown(le,ri,rt); int mid=(le+ri)>>1; if(v<=mid) { update(le,mid,lson,u,v,val); } else if(u>=mid+1) { update(mid+1,ri,rson,u,v,val); } else { update(le,mid,lson,u,mid,val); update(mid+1,ri,rson,mid+1,v,val); } pushup(le,ri,rt); } int query(int le,int ri,int rt,int u,int v) { if(vis[rt]!=-1) return (1<<vis[rt]); else if(le==u&&ri==v) { return sum[rt]; } pushdown(le,ri,rt); int res=0,mid=(le+ri)>>1; if(v<=mid) { res=query(le,mid,lson,u,v); } else if(u>=mid+1) { res=query(mid+1,ri,rson,u,v); } else { res=query(le,mid,lson,u,mid); res|=query(mid+1,ri,rson,mid+1,v); } return res; } int main() { while(~scanf("%d%d%d",&n,&tot,&m)) { memset(vis,-1,sizeof(vis)); memset(sum,0,sizeof(sum)); update(1,n,1,1,n,0); while(m--) { scanf("%s",s); int u,v,val; if(s[0]=='C') { scanf("%d%d%d",&u,&v,&val); if(u>v) swap(u,v); update(1,n,1,u,v,val-1); } else { if(u>v) swap(u,v); scanf("%d%d",&u,&v); int x=query(1,n,1,u,v),ans=0; while(x) { if(x&1) ans++; x>>=1; } printf("%d\n",ans); } } } return 0; } /* 2 2 4 C 1 1 2 P 1 2 C 2 2 2 P 1 2 */