hdu 5023 A Corrupt Mayor's Performance Art(线段树水题)

有n(1e6)个点,m(1e5)次询问,最多有30种颜色,有两种操作 p a b c,把区间a,b都变成颜色c,Q a b,查询a b间的颜色,并且按照值大小输出,初始所有点的颜色都是2

分析:线段树维护区间,因为最多有30种颜色,可以用30位的0/1表示该颜色是否存在,然后编码为数就好了,加个懒标就ok了

还有一点,用c交,跑的飞快

#include<stdio.h>
#include<string.h>

int flag[4000005],set[4000005];

void pushdown(int rt,int l,int r){
    int ls=rt<<1,rs=rt<<1|1;
    if(set[rt]>=0){
        flag[ls]=flag[rs]=set[ls]=set[rs]=set[rt];
        set[rt]=-1;
    }
}

void update(int rt,int l,int r,int ql,int qr,int v){
    if(ql<=l&&qr>=r){
        set[rt]=flag[rt]=v;
        return ;
    }
    int mid=(l+r)/2;
    if(set[rt]>=0)pushdown(rt,l,r);
    if(ql<=mid)update(rt*2,l,mid,ql,qr,v);
    if(qr>mid)update(rt*2+1,mid+1,r,ql,qr,v);
    flag[rt]=flag[rt*2]|flag[rt*2+1];
}

int query(int rt,int l,int r,int ql,int qr){
    if(ql<=l&&qr>=r){     return  flag[rt];}
    int mid=(l+r)/2;
    int ans=0;
    if(set[rt]>=0)pushdown(rt,l,r);
    if(ql<=mid)ans=ans|query(rt*2,l,mid,ql,qr);
    if(qr>mid)ans=ans|query(rt*2+1,mid+1,r,ql,qr);
    return ans;
}

void getans(int t){
    int ans[35],d=0,i;
    for(i=0;i<30;i++)
        if(t&(1<<i))ans[d++]=i+1;
    for(i=0;i<d;i++){
        if(i)putchar(' ');
        printf("%d",ans[i]);
    }
    puts("");
}
int n,m;


int main(){
    while(~scanf("%d%d",&n,&m)&&n+m){

        memset(set,-1,sizeof(set));
        update(1,1,n,1,n,2);
        char s;int a,b,c;
        while(m--){
            getchar();
            scanf("%c%d%d",&s,&a,&b);
            if(s=='P'){
                scanf("%d",&c);
                update(1,1,n,a,b,(1<<(c-1)));
            }
            else{
                int tmp=query(1,1,n,a,b);
                getans(tmp);
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jihe/p/5806432.html