您的位置:首页 > 其它

POJ 2777 Count Color (二进制或 线段树)

2016-02-29 09:10 447 查看
由于T不超过30,可以用一个数表示当前区间的已有颜色,或操作来pushup每一个区间

#include<cstring>
#include<string>
#include<iostream>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstdlib>
#include<cmath>
#include<vector>
//#pragma comment(linker, "/STACK:1024000000,1024000000");

using namespace std;

#define INF 0x3f3f3f3f
#define maxn 400000

int n,m,q;
struct node
{
int l,r;
int val;
int add;
} T[maxn];

void init(int l,int r,int k)
{
T[k].l=l;
T[k].r=r;
T[k].val=1;
T[k].add=0;
if(l==r) return ;
int mid=(l+r)>>1;
init(l,mid,2*k);
init(mid+1,r,2*k+1);
}

inline void pushup(int k)
{
T[k].val=(T[2*k].val|T[2*k+1].val);
}

inline void pushdown(int k)
{
if(T[k].add==0||T[k].l==T[k].r) return ;
T[2*k].add=T[2*k+1].add=T[k].add;
T[2*k].val=T[2*k+1].val=(1<<(T[k].add-1));
T[k].add=0;
}

void update(int d,int l,int r,int k)
{
if(T[k].l==l&&T[k].r==r)
{
T[k].val=(1<<(d-1));
T[k].add=d;
return ;
}
pushdown(k);
int mid=(T[k].l+T[k].r)>>1;
if(r<=mid) update(d,l,r,2*k);
else if(l>mid) update(d,l,r,2*k+1);
else
{
update(d,l,mid,2*k);
update(d,mid+1,r,2*k+1);
}
pushup(k);
}

int query(int l,int r,int k)
{
if(T[k].l==l&&T[k].r==r)
{
return T[k].val;
}
pushdown(k);
int mid=(T[k].l+T[k].r)>>1;
if(r<=mid) return query(l,r,2*k);
else if(l>mid) return query(l,r,2*k+1);
else return (query(l,mid,2*k)|query(mid+1,r,2*k+1));
}

int main()
{
while(scanf("%d%d%d",&n,&m,&q)!=EOF)
{
init(1,n,1);
char str[5];
while(q--)
{
scanf("%s",str);
if(str[0]=='C')
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(a>b) swap(a,b);
update(c,a,b,1);
}
else
{
int a,b;
scanf("%d%d",&a,&b);
if(a>b) swap(a,b);
int ans=query(a,b,1);
int c=0;
while(ans>0)
{
if(ans%2) c++;
ans>>=1;
}
printf("%d\n",c);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: