您的位置:首页 > 其它

POJ 2777 Count Color 线段树一些容易遗漏的东西……

2010-11-17 00:43 302 查看
成段更新,区间统计,

把query里的传递给子节点的步骤,切记!!

向大牛学习……http://www.notonlysuccess.com/?p=59

#include<iostream>
using namespace std;
int countbit(unsigned int n)
{
int count=0;
while(n!=0) {
n &= n-1;
count++;
}
return count;
}

int two(int n)
{
return 1<<n;
}
struct seg_tree
{
int left; int right; int col; bool cover;
int calmid()
{
return (left+right)>>1;
}
};

struct seg_tree tree[100000*3];
void build(int left,int right,int idx)
{
tree[idx].left = left;
tree[idx].right = right;
tree[idx].cover=1;
tree[idx].col=two(1);
if(left == right)
return;
int mid=tree[idx].calmid();
build(left,mid,idx<<1);
build(mid+1,right,idx<<1|1);
}
int query(int left,int right,int idx)
{
if(left == tree[idx].left && right==tree[idx].right)
{
return tree[idx].col;
}

if(tree[idx].cover)
{
tree[idx<<1].col=tree[idx<<1|1].col=tree[idx].col;
tree[idx<<1].cover=tree[idx<<1|1].cover=1;
tree[idx].cover=0;
}

int mid=tree[idx].calmid();
if(right<=mid)
return query(left,right,idx<<1);
else if(left>mid)
return query(left,right,idx<<1|1);
else
return query(left,mid,idx<<1) | query(mid+1,right,idx<<1|1);
}

void update(int left,int right,int val,int idx)
{
if(left <= tree[idx].left && right >= tree[idx].right )
{
tree[idx].col=two(val);
tree[idx].cover=1;
return;
}
if(tree[idx].cover)
{
tree[idx<<1].col=tree[idx<<1|1].col=tree[idx].col;
tree[idx<<1].cover=tree[idx<<1|1].cover=1;
tree[idx].cover=0;
}
int mid=tree[idx].calmid();
if(left<=mid) update(left,right,val,idx<<1);
if(right>mid) update(left,right,val,idx<<1|1);
tree[idx].col=tree[idx<<1].col | tree[idx<<1|1].col;
}

int main()
{
freopen("in.txt","r",stdin);
int n,m,p;
cin>>n>>m>>p;
build(1,n,1);
while(p--)
{
char c;
getchar();
scanf("%c",&c);
if(c=='C')
{
int x,y,color;
scanf("%d%d%d",&x,&y,&color);
if(x>y) swap(x,y);
update(x,y,color,1);
}
else if(c=='P')
{
int a,b;
scanf("%d%d",&a,&b);
if(a>b) swap(a,b);
printf("%d/n",countbit(query(a,b,1)));
}
}
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: