poj 2777 线段树

平生第一道线段树,A的太艰难了,一开始就RE,以为是数组开小了,增加了之后仍然RE,看了discuss后才知道文中有一就话没看到,“here A, B, C are integers, and A may be larger than B”,原来left可以大于right,改了之后结果TLE,我可纠结的不得了。后来看到一些大牛的博客中写道要用延迟操作,结果终于弄懂了什么是延迟操作。修改之后再提交结果WA(悲哉),后来自己做了一些测试数据,却发现自己仅在涂色的时候进行了延迟操作,其实在查找的时候仍然需要,修改之后AC了。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAX_LEN 200010
struct node
{
	int left;
	int right;
	int color;
	int sign;
};
node tree[MAX_LEN*2];
int sum;
int makeTree(int left,int right,int k)
{
	int mid;
	tree[k].color=1;
	tree[k].left=left;
	tree[k].right=right;
	tree[k].sign=0;
	if(left==right) return 0;
	mid=(left+right)>>1;
	makeTree(left,mid,k<<1);
	makeTree(mid+1,right,(k<<1)+1);
	return 0;
}
inline int push(int k)
{
	tree[k].sign=0;
	if(tree[k].left<tree[k].right)
	{
		tree[k<<1].color=tree[k].color;
		tree[(k<<1)+1].color=tree[k].color;
		tree[k<<1].sign=tree[(k<<1)+1].sign=1;
	}
	return 0;
}
int tintage(int left,int right,int color,int k)
{
	int mid;
	if(tree[k].left==left && tree[k].right==right)
	{
		tree[k].color=1<<(color-1);
		tree[k].sign=1;
		return 0;
	}
	if(tree[k].sign)  push(k);
	mid=(tree[k].left+tree[k].right)>>1;
    if(right<=mid)
		tintage(left,right,color,k<<1);
	else if(left>mid)
		tintage(left,right,color,(k<<1)+1);
	else
	{
		tintage(left,mid,color,k<<1);
		tintage(mid+1,right,color,(k<<1)+1);
	}
    tree[k].color=tree[k<<1].color|tree[(k<<1)+1].color;
	return 0;
}
int calculate(int color)
{
	int i,j=1,k=0;
	for(i=0;i<30;j=(1<<++i))
		if(color&j) k++;
	return k;
}
int query(int left,int right,int k)
{
	int mid;
	if(tree[k].left==left && tree[k].right==right)
	{
		sum=sum|tree[k].color;
		return 0;
	}
	if(tree[k].sign) push(k);
	mid=(tree[k].left+tree[k].right)>>1;
	if(right<=mid)
		query(left,right,k<<1);
	else if(left>mid)
		query(left,right,(k<<1)+1);
	else
	{
		query(left,mid,k<<1);
		query(mid+1,right,(k<<1)+1);
	}
	return 0;
}
int main()
{
	int i,m,n,len,color,left,right,temp;
	char c[10];
	while(scanf("%d%d%d",&len,&m,&n)!=EOF)
	{
		makeTree(1,len,1);
		for(i=0;i<n;i++)
		{
			scanf("%s",c);
			if(c[0]=='C')
			{
				scanf("%d%d%d",&left,&right,&color);
				if(left>right) {temp=left,left=right,right=temp;}
                tintage(left,right,color,1);
			}
			if(c[0]=='P')
			{
				sum=0;
				scanf("%d%d",&left,&right);
				if(left>right) {temp=left,left=right,right=temp;}
				query(left,right,1);
				printf("%d\n",calculate(sum));
			}
		}
	}
	return 0;
}
posted @ 2011-09-21 20:11  书山有路,学海无涯  阅读(311)  评论(0编辑  收藏  举报