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

来源:互联网 发布:入门音响推荐 知乎 编辑:程序博客网 时间:2024/04/28 23:38

由于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 400000int 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;}


0 0