题目链接:poj 2777
给定一段区间,对该区间进行染色,询问操作
染色操作对特定的区间进行染色
询问操作求对应区间中节点颜色的种类总数
线段树操作,因为颜色种类总数一共就30种,因此可以在节点中用用二进制表示区间中有的颜色。
/******************************************************
* File Name: 2777.cpp
* Author: kojimai
* Creater Time:2014年08月30日 星期六 00时25分57秒
******************************************************/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
struct seg
{
int l,r,c;//c用二进制来表示当前段中颜色的种类
bool flag;//表示当前段被涂上同样的颜色
}node[500005];
void buildtree(int l,int r,int num)
{
node[num].l=l;
node[num].r=r;
node[num].flag=true;
node[num].c=1;
if(l==r)
return;
int mid=(l+r)/2;
buildtree(l,mid,num*2);
buildtree(mid+1,r,num*2+1);
}
int Count(int x)
{
int ret=0;
while(x)
{
if(x%2==1)
ret++;
x/=2;
}
return ret;
}
void update(int l,int r,int c,int num)
{
if(node[num].l>=l&&node[num].r<=r)
{
node[num].c=(1<<(c-1));
node[num].flag=true;
return;
}
if(node[num].flag)
{
node[num*2].flag=true;
node[num*2+1].flag=true;
node[num*2].c=node[num].c;
node[num*2+1].c=node[num].c;
node[num].flag=false;
}
int mid=(node[num].l+node[num].r)/2;
if(mid>=r)
update(l,r,c,num*2);
else if(mid<l)
update(l,r,c,num*2+1);
else
{
update(l,mid,c,num*2);
update(mid+1,r,c,num*2+1);
}
node[num].c=node[num*2].c|node[num*2+1].c;
return;
}
int query(int l,int r,int num)
{
//cout<<"l="<<l<<" r="<<r<<" nodel="<<node[num].l<<" noder="<<node[num].r<<" c="<<node[num].c<<endl;
if(node[num].l==l&&node[num].r==r)
{
return node[num].c;
}
if(node[num].flag)
{
node[num*2].flag=node[num*2+1].flag=true;
node[num*2].c=node[num].c;
node[num*2+1].c=node[num].c;
node[num].flag=false;
}
int mid=(node[num].l+node[num].r)/2;
if(mid>=r)
return query(l,r,num*2);
else if(mid<l)
return query(l,r,num*2+1);
else
{
return query(l,mid,num*2)|query(mid+1,r,num*2+1);
}
}
int main()
{
int L,t,q;
while(~scanf("%d%d%d",&L,&t,&q))
{
buildtree(1,L,1);
char ch;
int x,y,z;
while(q--)
{
getchar();
scanf("%c",&ch);
//cout<<ch<<endl;
if(ch=='C')
{
scanf("%d%d%d",&x,&y,&z);
if(x>y)
swap(x,y);
update(x,y,z,1);
}
else
{
scanf("%d%d",&x,&y);
if(x>y)
swap(x,y);
int sum=query(x,y,1);
cout<<Count(sum)<<endl;
}
}
}
return 0;
}