C POJ 2777 Count Color 区间更新+压缩

有两种操作,一个是更新区间内颜色,一个是询问区间内不同颜色的个数

因为颜色最多只有30种,所以把区间内颜色数压成一个数字即可,如果(1<

因为是区间更新,所以再加个延时标记就好了。

/*===============*\
| *** *** *** *** |
|  *  **  *   * * |
| *** *** *   *** |
|    ID: ZERO     |
|    LANG: C++    |
\*===============*/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define mod (int)(1e9+7)
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define maxn 100001
int col[maxn<<2];
bool up[maxn<<2];
int upit[maxn<<2];
void PushUP(int rt) { //向上更新
    col[rt] = col[rt<<1]|col[rt<<1|1];
}
void PushDown(int rt,int l,int r,int now){ //向下更新
    col[now]=col[rt];
    if(l!=r){
        up[now]=true;
        upit[now]=col[rt];
    }
}
void build(int co,int l,int r,int rt) {//建树
    up[rt]=false;
    if (l == r) {
        col[rt]=co;
        return ;
    }
    int m = (l + r) >> 1;
    build(co,lson);
    build(co,rson);
    PushUP(rt);
}
void update(int ll,int rr,int sc,int l,int r,int rt) {//更新
    if (l >=ll && r<=rr) {
        col[rt] = sc;
        if(l!=r) {up[rt]=true;upit[rt]=sc;}  //延时标记
        return ;
    }
    int m=(l+r) >> 1;//middle
    if(up[rt]){//触发延时标记
        PushDown(rt,lson);
        PushDown(rt,rson);
        up[rt]=false;
    }
    
    if (ll<=m&&rr>=l)     update(ll,rr , sc , lson);
    if (ll<=r&&rr>=m+1) update(ll,rr , sc , rson);
    PushUP(rt);
}
int query(int L,int R,int l,int r,int rt) {//询问
    if (L <= l && r <= R) {
        return col[rt];
    }
    int m=(l+r) >> 1;//middle
    if(up[rt]){
        PushDown(rt,lson);
        PushDown(rt,rson);
        up[rt]=false;
    }
    
    int ret = 0;
    if (L <= m) ret = ret|query(L,R,lson);
    if (R > m) ret = ret|query(L,R,rson);
    return ret;
}
char s[2];
int main(){
    int n,m,t;
    while (~scanf("%d%d%d",&n,&t,&m)) {
        build(1,1,n,1);//建树
        while (m--) {
            int l,r,co;
            scanf("%s%d%d",s,&l,&r);
            int tt;
            if(l>r) tt=l,l=r,r=tt;// A may be larger than B 这条件你妹的!
            if(s[0]=='C'){
                scanf("%d",&co);
                update(l,r,1<<(co-1),1,n,1);
            }
            else{
                int nn=query(l,r,1,n,1),ans=0;
                for(int i=0;i


你可能感兴趣的:(C POJ 2777 Count Color 区间更新+压缩)