poj 2777 (线段树)

第一次建树时,根节点cover域为1。以后要涂色的时候,先看涂色区域是否覆盖当前节点的范围,如果覆盖,直接更改当前节点的cover域。否则,先看当前节点是否为纯色,如果是纯色,就要把纯色信息传递给左右子树,而当前节点cover域则变为0.表明当前节点覆盖的颜色不在是纯色,这样照着这个思路递归更新子节点的cover域。查询就比较简单了,中间用一个数组来表示哪些颜色已经上色。

#include<iostream>
#include
<cstdio>
#include
<cstring>
using namespace std;
#define MAXN 100010
#define colormax 100
struct Node
{
int left;
int right;
int cover;
} node[
3*MAXN];
int color[colormax];
char f[50];
void treemake(int a,int b,int id)
{
node[id].left
=a;
node[id].right
=b;
if(a==b) return;

int mid=(node[id].left+node[id].right)>>1;
treemake(a,mid,id
<<1);
treemake(mid
+1,b,(id<<1)+1);
}

void treeupdate(int a,int b,int col,int id)
{
if(a<=node[id].left&&b>=node[id].right)
node[id].cover
=col;
else
{
if(node[id].cover >0)
{
node[id
<<1].cover=node[id].cover;
node[(id
<<1)+1].cover=node[id].cover;
node[id].cover
=0;
}
int mid=(node[id].left+node[id].right)>>1;
if(a>mid)
treeupdate(a,b,col,(id
<<1)+1);
else if(b<=mid)
treeupdate(a,b,col,id
<<1);
else
{
treeupdate(a,mid,col,id
<<1);
treeupdate(mid
+1,b,col,(id<<1)+1);
}
}
}

void treequery(int a,int b,int id)
{
if(node[id].cover>0)
color[node[id].cover]
=1;
else
{
int mid=(node[id].left+node[id].right)>>1;
if(a>mid)
treequery(a,b,(id
<<1)+1);
else if(b<=mid)
treequery(a,b,id
<<1);
else
{
treequery(a,mid,id
<<1);
treequery(mid
+1,b,(id<<1)+1);
}
}
}
int main()
{
int l,t,n,i,j,a,b,c;
while(scanf("%d%d%d\n",&l,&t,&n)!=EOF)
{
treemake(
1,l,1);
node[
1].cover=1;
for(i=0;i<n;i++)
{
scanf(
"%s%d%d",f,&a,&b);
if(f[0]=='C')
{
scanf(
"%d",&c);
if(a>b) {l=a;a=b;b=l;}
treeupdate(a,b,c,
1);
}
else
{
if(a>b) {l=a;a=b;b=l;}
memset(color,
0,sizeof(color));
treequery(a,b,
1);
int sum=0;
for(j=1;j<=t;j++)
if(color[j]) sum++;
printf(
"%d\n",sum);
}
}
}
return 0;
}

posted on 2011-06-04 00:23  thinking001  阅读(122)  评论(0)    收藏  举报

导航