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;
}
昨天把这个写了一天,都木有写好,今天早上看了一下别人的代码,才算真正搞明白了,而且自己写的一次性过,不容易啊。
我觉得主要是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;
}
相关文章推荐
- poj 2777-Count Color解题报告
- POJ 2777 Count Color ---线段树
- poj 2777 Count Color 基础线段树,带给的初学者噩梦!!!
- POJ2777——Count Color(线段树)
- POJ 2777 Count Color(线段染色 区间更新)
- poj 2777 Count Color(线段树+lazy优化+位运算)
- poj 2777 Count Color (线段树 区间更新 染色)
- poj 2777 Count Color
- C POJ 2777 Count Color 区间更新+压缩
- 【POJ】2777 Count Color
- POJ 2777 Count Color(线段树 区间更新)
- poj 2777 Count Color(线段树区间更新)
- 【线段树】 POJ 2777 Count Color
- poj_2777Count Color线段树_区间更新
- POJ 2777 Count Color 线段树区间更新位运算
- poj 2777 Count Color
- poj2777——Count Color
- poj 2777 Count Color
- Count Color(poj 2777)
- poj 2777 Count Color(线段树)