您的位置:首页 > 其它

poj 2777 count color

2011-08-21 10:17 218 查看
http://poj.org/problem?id=2777

昨天把这个写了一天,都木有写好,今天早上看了一下别人的代码,才算真正搞明白了,而且自己写的一次性过,不容易啊。

我觉得主要是value用的比较好,当value==-1或者0的时候,表示以此为父节点的两个子节点中的颜色至少有两种以上,如果value!=-1或者0,表明颜色只用一种,而且是value

所代表的值,其他的地方看代码就很明白了。

#include<cstdio>

#include<cstring>

#include<iostream>

#include<algorithm>

using namespace std;

const int maxn=100002;

struct node

{

int l,r;

int value;//value==-1表示至少有两种以上的颜色,等于常数表示具体颜色

}tree[4*maxn];

int visit[32];

void Creat(int l,int r,int p)

{

tree[p].l=l;

tree[p].r=r;

tree[p].value=1;

if(l==r) return;

int mid=tree[p].l+tree[p].r>>1;

Creat(l,mid,p<<1);

Creat(mid+1,r,p<<1|1);

}

void update(int a,int b,int c,int p)

{

if(tree[p].l==a&&tree[p].r==b)

{

tree[p].value=c;

return;

}

if(tree[p].value==c) return;

int mid=tree[p].l+tree[p].r>>1;

if(tree[p].value!=-1)

{

tree[2*p].value=tree[p].value;

tree[2*p+1].value=tree[p].value;

tree[p].value=-1;

}

if(a>mid) update(a,b,c,p<<1|1);

else if(b<=mid) update(a,b,c,p<<1);

else

{

update(a,mid,c,p<<1);

update(mid+1,b,c,p<<1|1);

}

}

void get_sum(int a,int b,int p)

{

if(tree[p].value!=-1)

{

visit[tree[p].value]=1;return;

}

int mid=tree[p].l+tree[p].r>>1;

if(a>mid) get_sum(a,b,p<<1|1);

else if(b<=mid) get_sum(a,b,p<<1);

else

{

get_sum(a,mid,p<<1);

get_sum(mid+1,b,p<<1|1);

}

}

int l,t,op;

int a,b,c;

char ch[2];

int main()

{

scanf("%d%d%d",&l,&t,&op);

Creat(1,l,1);

while(op--)

{

scanf("%s",ch);

if(ch[0]=='C')

{

scanf("%d%d%d",&a,&b,&c);

update(a,b,c,1);

}

else if(ch[0]=='P')

{

scanf("%d%d",&a,&b);

memset(visit,0,sizeof(visit));

get_sum(a,b,1);

int ans=0;

for(int i=0;i<31;i++)

ans+=visit[i];

printf("%d\n",ans);

}

}

return 0;

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