POJ 2777 Count Color
2010-10-20 19:44
232 查看
很好的一道线段树的题,问你在区间[l,r]上共有几种颜色,由于颜色只有30种,故可以用二进制储存颜色,1表示颜色1,10表示颜色2,100表示颜色3……依次类推,二进制数位上有几个数字,就有几种颜色
当着色区间大于等于当前区间时,着色后就可以返回,不必继续对下面的小区间着色,因为一次只能着一个颜色,下面子区间的颜色肯定与父区间的相同,当下次访问该区间时,再更新子区间的颜色
还有要注意的就是 位运算优先级小于加法!!!
代码:
当着色区间大于等于当前区间时,着色后就可以返回,不必继续对下面的小区间着色,因为一次只能着一个颜色,下面子区间的颜色肯定与父区间的相同,当下次访问该区间时,再更新子区间的颜色
还有要注意的就是 位运算优先级小于加法!!!
代码:
#include<iostream> using namespace std; struct node { int left; int right; int color; }tree[510005]; int ans; int single(int a)//判断是否为单色 { if(a&(a-1)) return 0; else return 1; } void build(int num,int l,int r) { if(l==r) { tree[num].left=tree[num].right=l; tree[num].color=1; return; } tree[num].left=l; tree[num].right=r; int mid=(l+r)>>1; build(num<<1,l,mid); build((num<<1)+1,mid+1,r); tree[num].color=1; } void update(int num,int l,int r,int c) { if(tree[num].left>=l&&tree[num].right<=r)//着色区间包含该区间,则不必再对下面的子区间着色 { tree[num].color=c; return; } if(single(tree[num].color))//如果该区间为单色,下面的子区间可能还没更新,必须更新,否则递归函数向上返回更新父区间信息时会出错 { tree[num*2].color=tree[num*2+1].color=tree[num].color; } int mid=(tree[num].left+tree[num].right)>>1; if(mid>=r) { update(num<<1,l,r,c); } else if(mid<l) { update((num<<1)+1,l,r,c); } else { update(num<<1,l,mid,c); update((num<<1)+1,mid+1,r,c); } tree[num].color=(tree[num*2].color|tree[num*2+1].color); } void query(int num,int l,int r) { if(tree[num].left>=l&&tree[num].right<=r||single(tree[num].color))//如果不判断是否为单色,可能单色情况下子区间还没更新,去访问时出错 { ans|=tree[num].color; return; } /*if(single(tree[num].color)) { tree[num*2].color=tree[num*2+1].color=tree[num].color; }*/ int mid=(tree[num].left+tree[num].right)>>1; if(mid>=r) { query(num<<1,l,r); } else if(mid<l) { query((num<<1)+1,l,r); } else { query(num<<1,l,mid); query((num<<1)+1,mid+1,r); } } void cal() { int p=ans; ans=0; while(p) { if(p%2)//判断二进制数位上有几个1 ans++; p=p>>1; } } int main() { int l,t,oper,i,j,n,a,b,c,temp; char com; scanf("%d%d%d",&l,&t,&oper); build(1,1,l); while(oper--) { scanf("%c",&com); if(com==10) { oper++; continue; } if(com=='C') { scanf("%d%d%d",&a,&b,&c); if(a>b) { temp=a; a=b; b=temp; } update(1,a,b,1<<(c-1)); continue; } else if(com=='P') { scanf("%d%d",&a,&b); if(a>b) { temp=a; a=b; b=temp; } ans=0; query(1,a,b); cal(); printf("%d/n",ans); continue; } } system("pause"); return 0; }
相关文章推荐
- poj 2777 Count Color
- POJ 题目2777 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(线段树染色)
- POJ 2777 Count Color
- POJ 2777 Count Color (线段树的区间更新+lazy tag)
- 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