POJ-2777

来源:互联网 发布:网络管理基本功能 编辑:程序博客网 时间:2024/06/07 00:41

题意

给定一个区间长度为l,共有t种颜色,o个操作。
C a b x 表示把a到b染成第x种颜色,P a b 表示查询a b间共有几种颜色。
初始状态下所有颜色为1,我就是因为这一点WA了几次


题解

t最大才30,颜色直接二进制压缩即可,不要每次修改a b间所有的点,lazy一下就好了


常数巨大的丑陋代码

# include <stdio.h># include <stdlib.h># include <iostream># include <string.h># include <algorithm>using namespace std;# define IL inline# define RG register# define UN unsigned# define ll long long# define rep(i, a, b) for(RG int i = a; i <= b; i++)# define per(i, a, b) for(RG int i = b; i >= a; i--)# define mem(a, b) memset(a, b, sizeof(a))# define max(a, b) ((a) > (b)) ? (a) : (b)# define min(a, b) ((a) < (b)) ? (a) : (b)# define Swap(a, b) a ^= b, b ^= a, a ^= b;IL int Get(){    RG char c = '!'; RG int x = 0, z = 1;    while(c != '-' && (c < '0' || c > '9')) c = getchar();    if(c == '-') z = -1, c = getchar();    while(c >= '0' && c <= '9') x=x*10+c-'0', c = getchar();    return x*z;}const int MAXM = 2000001;struct Tree{    int l, r, cover, color;} tree[MAXM];//color状压颜色 IL void Updata(RG int now){    tree[now].color = tree[now<<1].color|tree[now<<1|1].color;}IL void Pushdown(RG int now){    if(!tree[now].cover) return;    tree[now<<1|1].cover = tree[now<<1].cover = 1;    tree[now<<1|1].color = tree[now<<1].color = tree[now].color;    tree[now].cover = 0;}IL void Build(RG int now, RG int l, RG int r){    tree[now] = (Tree) {l, r, 1, 1};    if(l == r) return;    RG int mid = l+r>>1;    Build(now<<1, l, mid); Build(now<<1|1, mid+1, r);    Updata(now);}IL int Query(RG int now, RG int l, RG int r){    if(tree[now].cover || (tree[now].l == l && tree[now].r == r)) return tree[now].color;    Pushdown(now);    RG int mid = tree[now].l+tree[now].r>>1, t = 0;    if(mid < l) t = Query(now<<1|1, l, r);    if(mid >= l && mid < r) t = Query(now<<1, l, mid)|Query(now<<1|1, mid+1, r);    if(mid >= r) t = Query(now<<1, l, r);    Updata(now);    return t;}IL void Add(RG int now, RG int l, RG int r, RG int x){    if(tree[now].l == l && tree[now].r == r){        tree[now].cover = 1; tree[now].color = x;        return;    }    if(tree[now].color == x) return;    Pushdown(now);    RG int mid = tree[now].l+tree[now].r>>1;    if(mid < l) Add(now<<1|1, l, r, x);    if(mid >= l && mid < r) Add(now<<1, l, mid, x), Add(now<<1|1, mid+1, r, x);    if(mid >= r) Add(now<<1, l, r, x);    Updata(now);}int main(){    RG int l = Get(), t = Get(), o = Get();    Build(1, 1, l);    rep(i, 1, o){        char c;        scanf(" %c", &c);        if(c == 'C'){            RG int a = Get(), b = Get(), x = Get();            Add(1, a, b, 1<<(x-1));        }        else if(c == 'P'){            RG int a = Get(), b = Get();            RG int t = Query(1, a, b), ans = 0;            while(t){                ans++;                t -= (t&-t);            }            printf("%d\n", ans);        }    }    return 0;}