标签:des style io ar color os sp strong on
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 36646 | Accepted: 11053 |
Description
Input
Output
Sample Input
2 2 4 C 1 1 2 P 1 2 C 2 2 2 P 1 2
Sample Output
2 1
题意就是求一段墙壁颜色种类,因为颜色种类最多30,可以用二进制表示颜色的总数。
#include<cstdio> #include<cmath> #include<queue> #include<iostream> #include<algorithm> using namespace std; #define ll __int64 #define N 100005 struct node { int l,r; int s,v,f; //颜色种类二级制表示,区间颜色、是否需要向下更新 }f[N*3]; void creat(int t,int l,int r) { f[t].l=l; f[t].r=r; f[t].v=1; f[t].f=0; f[t].s=1; //起始颜色为1,可以用二进制表示 if(l==r) { return ; } int tmp=t<<1,mid=(l+r)>>1; creat(tmp,l,mid); creat(tmp|1,mid+1,r); } void update(int t,int l,int r,int v) { int tmp=t<<1,mid=(f[t].l+f[t].r)>>1; if(f[t].l==l&&f[t].r==r) { f[t].v=v; f[t].s=(1<<v); f[t].f=1; return ; } if(f[t].f) //向下更新 { f[tmp].f=f[tmp|1].f=1; f[tmp].v=f[tmp|1].v=f[t].v; f[tmp].s=f[tmp|1].s=(1<<f[t].v); f[t].f=0; } if(r<=mid) update(tmp,l,r,v); else if(l>mid) update(tmp|1,l,r,v); else { update(tmp,l,mid,v); update(tmp|1,mid+1,r,v); } f[t].f=0; //向上求和 f[t].s=f[tmp].s|f[tmp|1].s; } int query(int t,int l,int r) { if(f[t].l==l&&f[t].r==r) { return f[t].s; } int tmp=t<<1,mid=(f[t].l+f[t].r)>>1; if(f[t].f) { f[tmp].f=f[tmp|1].f=1; f[tmp].v=f[tmp|1].v=f[t].v; f[tmp].s=f[tmp|1].s=(1<<f[t].v); f[t].f=0; } if(r<=mid) return query(tmp,l,r); else if(l>mid) return query(tmp|1,l,r); else { return query(tmp,l,mid)|query(tmp|1,mid+1,r); } } int main() { int n,t,q,l,r,c; char ch; while(~scanf("%d%d%d",&n,&t,&q)) { creat(1,1,n); while(q--) { getchar(); scanf("%c ",&ch); if(ch=='C') { scanf("%d%d%d",&l,&r,&c); if(l>r) swap(l,r); update(1,l,r,c-1); } else { scanf("%d%d",&l,&r); if(l>r) swap(l,r); int tmp=query(1,l,r),ans=0; while(tmp) { if(tmp&1) ans++; tmp>>=1; } printf("%d\n",ans); } } } return 0; }
poj 2777 Count Color (成段更新+区间求和)
标签:des style io ar color os sp strong on
原文地址:http://blog.csdn.net/u011721440/article/details/41631295