POJ-2777

题意

给定一个区间长度为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
", ans);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/cjoieryl/p/8206412.html