[日常摸鱼][poj2777]Count Color-线段树
辣鸡会考考完啦哈哈哈哈
题意:一块板分成$L$块,每次给一段连续的块染色或者询问一段有几种颜色,颜色的范围$\leq 30$
我记得我好像做过一个类似的二维染色的问题…不过那个用树状数组直接过掉了…
这题颜色范围这么小的范围直接想到线段树了吧,直接把一个区间的颜色二进制按位压缩成一个状态,维护区间或
题面还特地说了可能$a>b$…然而我没看到
#include<cstdio> const int N=100005; inline int read() { int s=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){s=s*10+c-'0';c=getchar();} return s*f; } int n,o,t; int tr[N<<2],tag[N<<2]; char s[5]; inline void swap(int &a,int &b){int t=a;a=b;b=t;} #define lson (node<<1) #define rson (node<<1|1) inline void push_up(int node) { tr[node]=tr[lson]|tr[rson]; } inline void push_down(int node,int l,int r) { if(tag[node]==-1)return; tag[lson]=tag[rson]=tag[node]; tr[lson]=tr[rson]=(1<<(tag[node]-1)); tag[node]=-1; } inline void build(int node,int l,int r) { tag[node]=-1;tr[node]=1; if(l==r)return; int mid=(l+r)>>1; build(lson,l,mid);build(rson,mid+1,r); } inline void modify(int node,int l,int r,int ql,int qr,int v) { if(ql<=l&&r<=qr) { tag[node]=v; tr[node]=(1<<(v-1)); return; }push_down(node,l,r); int mid=(l+r)>>1; if(mid>=ql)modify(lson,l,mid,ql,qr,v); if(mid+1<=qr)modify(rson,mid+1,r,ql,qr,v); push_up(node); } inline int query(int node,int l,int r,int ql,int qr) { if(ql<=l&&r<=qr)return tr[node]; push_down(node,l,r);int res=0,mid=(l+r)>>1; if(mid>=ql)res|=query(lson,l,mid,ql,qr); if(mid+1<=qr)res|=query(rson,mid+1,r,ql,qr); return res; } int main() { //freopen("input.in","r",stdin); n=read();t=read();o=read(); build(1,1,n); for(register int i=1;i<=o;i++) { scanf("%s",s+1); if(s[1]=='C') { int a,b,c;a=read();b=read();c=read(); if(a>b)swap(a,b);modify(1,1,n,a,b,c); }else{ int a,b;a=read();b=read(); if(a>b)swap(a,b); int sum=query(1,1,n,a,b),res=0; for(register int k=0;k<=32;k++) { if(sum&(1ll<<k))res++; }printf("%d\n",res); } } return 0; }