HDU-5023 线段树染色问题+延时标记

来源:互联网 发布:泰瑞克埃文斯生涯数据 编辑:程序博客网 时间:2024/06/15 10:11

题意

给我们1-n的区间段 两种操作
P a b c 表示把a到b染成c颜色
Q a b 表示求a到b的颜色种类数量
注意初始全部先染成颜色2

分析

线段树经典染色问题
可以用二进制来表示颜色数量 一共30个颜色 那么最多也就是30位 不会超过int的范围 二进制下第x位为1表示有x+1的颜色
父节点可以用”|”运算来统计两个子节点的信息

CODE

#include<bits/stdc++.h>#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1using namespace std;typedef long long ll;const int maxn = 1000010;struct tree{    int color,tag;//延时标记}T[maxn<<2];void build(int l,int r,int rt){    T[rt].tag=0;//注意这里要初始化树中的每个点都要初始化成0 才不会出错    if(l==r){        T[rt].color=2;        return;    }    int mid = (l+r)>>1;    build(lson);    build(rson);    T[rt].color = T[rt<<1].color | T[rt<<1|1].color;}void push_down(int l,int r,int rt){    if(T[rt].tag){        T[rt<<1].color = T[rt<<1|1].color = T[rt].tag;        T[rt<<1].tag = T[rt<<1|1].tag = T[rt].tag;        T[rt].tag=0;    }}void update(int s,int e,int cor,int l,int r,int rt){    if(s<=l&&e>=r){        T[rt].color = 1<<(cor-1);        T[rt].tag = 1<<(cor-1);        return;    }    push_down(l,r,rt);    int mid = (l+r)>>1;    if(s<=mid)update(s,e,cor,lson);    if(e>=mid+1)update(s,e,cor,rson);    T[rt].color = T[rt<<1].color|T[rt<<1|1].color;}int query(int s,int e,int l,int r,int rt){    if(s<=l&&e>=r)return T[rt].color;    push_down(l,r,rt);    int mid = l+r>>1;    int ans=0;    if(s<=mid)ans|=query(s,e,lson);    if(e>=mid+1)ans|=query(s,e,rson);    return ans;}int main(){    int n,m;    while(scanf("%d%d",&n,&m))    {        if(n==0&&m==0)return 0;        char cc[3];        build(1,n,1);        while(m--)        {            int a,b,c;            scanf(" %s",cc);            if(cc[0]=='P')            {                scanf("%d%d%d",&a,&b,&c);                update(a,b,c,1,n,1);            }            else            {                scanf("%d%d",&a,&b);                int ans = query(a,b,1,n,1);                bool f=0;                while(ans){                    if(ans&1){                        if(f)printf(" %d",cnt);                        else printf("%d",cnt),f=1;                    }                    cnt++;                    ans>>=1;                }                puts("");            }        }    }    return 0;}
原创粉丝点击