POJ 2777 Count Color
线段树区间变化, 用2进制保存颜色。。
#include<algorithm> #include<cstring> #include<vector> #include<cstdio> #include<cmath> #include<queue> using namespace std; #define LL(x) (x<<1) #define RR(x) (x<<1|1) int two(int x) { return 1<<(x-1); } struct Tree { int l, r, col, va; } T[100002<<2]; void build(int p,int l,int r) { T[p].l=l, T[p].r=r, T[p].col=-1, T[p].va=1;; if(l==r) return; int m=(l+r)>>1; build(LL(p),l,m); build(RR(p),m+1,r); } void PushDown(int p) { if(T[p].col!=-1) { T[LL(p)].va=T[RR(p)].va=T[p].col; T[LL(p)].col=T[RR(p)].col=T[p].col; T[p].col=-1; } } void PushUp(int p) { T[p].va=T[LL(p)].va|T[RR(p)].va; } void change(int p,int l,int r,int va) { if(l<=T[p].l&&T[p].r<=r) { T[p].va=va; T[p].col=va; return; } PushDown(p); int m=(T[p].l+T[p].r)>>1; if(l<=m) change(LL(p),l,r,va); if(r>m) change(RR(p),l,r,va); PushUp(p); } int query(int p,int l,int r) { if(l<=T[p].l&&T[p].r<=r) return T[p].va; PushDown(p); int m=(T[p].l+T[p].r)>>1; int ret; if(r<=m) ret=query(LL(p),l,r); else if(l>m) ret=query(RR(p),l,r); else ret=query(LL(p),l,m)|query(RR(p),m+1,r); return ret; } int main() { int n, t, o, l, r, c, ans; char op[3]; while(scanf("%d%d%d",&n,&t,&o)!=EOF) { build(1,1,n); while(o--) { scanf("%s",op); if(op[0]=='C') { scanf("%d%d%d",&l,&r,&c); if(l>r) swap(l,r); change(1,l,r,two(c)); } else { scanf("%d%d",&l,&r); if(l>r) swap(l,r); int tmp=query(1,l,r); ans=0; while(tmp!=0) { if(tmp%2==1) ans++; tmp/=2; } printf("%d\n",ans); } } } return 0; }