您的位置:首页 > 其它

poj 2777 线段树难题

2015-08-21 21:41 344 查看
题意:

给一个固定长度为L的画板,有两个操作:

C A B C:区间AB内涂上颜色C。

思路:线段树的好题,线段树 + lazy思想的经典应用。而且和位运算结合到了一起。因为颜色数量很少,而且父结点的颜色正好是两个子结点颜色的按位或,因此可以用位运算。最后1的个数就是不同颜色的个数。P A B:查询区间AB内颜色种类数。

参考博客:点击打开链接

#include<iostream>
#include<stdio.h>
using namespace std;
int l,t,o;
const int L=100005,T=35,O=100005;
int colour;
void swap(int &a,int &b)
{
	int t=a;
	a=b;
	b=t;
}
struct Node
{
	int l,r;
	int color;
	bool cover;
}node[6*L];
void build(int index,int l,int r)
{
	node[index].l=l;
	node[index].r=r;
	node[index].color|=1;
	if(l==r)
	{
		return;
	}
	int mid=(l+r)/2;
	build(index<<1,l,mid);
	build((index<<1)+1,mid+1,r);
}
void insert(int index,int begin,int end,int value)
{
	if(node[index].l==begin&&node[index].r==end)
	{
		node[index].color=(1<<(value-1));
		node[index].cover=true;
		return;
	}
	if(node[index].cover)
	{
		node[index].cover=false;
		node[index<<1].cover=true;
		node[(index<<1)+1].cover=true;
		node[index<<1].color=node[index].color;
		node[(index<<1)+1].color=node[index].color;
	}
	int mid=(node[index].l+node[index].r)/2;
	if(end<=mid)
	{
		insert(index<<1,begin,end,value);
	}
	else if(begin>mid)
	{
		insert((index<<1)+1,begin,end,value);
	}
	else
	{
		insert(index<<1,begin,mid,value);
		insert((index<<1)+1,mid+1,end,value);
	}
	node[index].color=node[index*2].color | node[index*2+1].color;
}
void query(int index,int begin,int end)
{
	if(node[index].cover||(begin==node[index].l&&end==node[index].r))
	{
		colour|=node[index].color;
		return;
	}
	int mid=(node[index].l+node[index].r)/2;
	if(end<=mid)
	{
		query(index<<1,begin,end);
	}
	else if(begin>mid)
	{
		query((index<<1)+1,begin,end);
	}
	else
	{
		query((index<<1),begin,mid);
		query((index<<1)+1,mid+1,end);
	}
}
int main()
{
	scanf("%d%d%d",&l,&t,&o);
	char a[2];
	int from,to,color;
	build(1,1,l);
	for(int i=1;i<=o;i++)
	{
		scanf("%s",&a);
		scanf("%d%d",&from,&to);
		if(from>to)
			swap(from,to);
		if(a[0]=='C')
		{
			scanf("%d",&color);
			insert(1,from,to,color);
		}
		else
		{
			int ans=0;
			colour=0;
			query(1,from,to);
			for(int i=0;i<t;i++)
			{
				if(colour&(1<<i))
					ans++;
			}
			printf("%d\n",ans);
		}
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: