• POJ 2777


    传送门

    题目要求支持两个操作

    C x  y  v   将区间[x,y]内木块全染成v色。

    P x  y   回答区间[x,y]中不同颜色的个数。 

    思路:

    下放标记,然后进行状态压缩。

    对,就是这样。

    压缩的状态中表示当前段存在哪几种颜色。

    最后询问操作返回的是一个压缩的值。

    这个时候我们就要统计返回值的二进制中1的个数。

    可以用以下代码快速解决。

    while(x){

      count++;

      x = x&(x-1);

    }

    至于为什么?

    不赘述。

    下面帖代码,有问题留言。

    #include<cstdio>
    #include<algorithm>
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define N 1000009
    using namespace std;
    
    int w[N<<2|1],add[N<<2|1];
    
    void update(int rt){            //左子树与右子树合并
        w[rt] = (w[rt<<1]|w[rt<<1|1]);
    }
    
    void build(int l,int r,int rt){
        if(l == r){
            w[rt] |= 1;         //初始化为1
            add[rt] = 0;
            return;
        }
        int m = (l+r)>>1;
        build(lson);
        build(rson);
        update(rt);
    }
    
    void color(int l,int r,int rt,int v){
        w[rt] &= 0;
        w[rt] |= (1<<(v-1));
        add[rt] = v;
    }
    
    void push_col(int l,int r,int rt){
        if(add[rt]){                    //0代表没有标记,否则是标记了,那么下放标记
            int m = (l+r)>>1;
            color(lson,add[rt]);
            color(rson,add[rt]);
            add[rt] = 0;
        }
    }
    
    void modify(int l,int r,int rt,int nowl,int nowr,int v){
        if(nowl <= l && r <= nowr){
            color(l,r,rt,v);
            return;
        }
        push_col(l,r,rt);
        int m = (l+r)>>1;
        if(nowl <= m)modify(lson,nowl,nowr,v);
        if(m < nowr)modify(rson,nowl,nowr,v);
        update(rt);
    }
    
    int query(int l,int r,int rt,int nowl,int nowr){
        if(nowl <= l && r <= nowr)return w[rt];
        push_col(l,r,rt);
        int m = (l+r)>>1;
        long long  ans = 0;
        if(nowl <= m) ans |= query(lson,nowl,nowr);     //左边与右边要合并
        if(m < nowr)ans |= query(rson,nowl,nowr);
        return ans;
    }
    
    int read(){                             //读入优化
        int x = 0;
        char ch = getchar();
        while(ch < '0' || ch > '9')ch = getchar();
        while(ch >= '0' && ch <= '9'){
            x =x * 10 + ch -'0';
            ch = getchar();
        }
        return x;
    }
    
    int main(){
        int n = read(),t = read(),m = read();
        build(1,n,1);
        while(m--){
            char cmd[2];
            scanf("%s",cmd);
            if(cmd[0] == 'C'){
                int x = read(),y = read(),v =read();
                if(x > y)swap(x,y);
                modify(1,n,1,x,y,v);
            }
            else {
                int x = read(),y =read();
                if(x > y)swap(x,y);
                int ans = query(1,n,1,x,y);
                int count = 0;
                while(ans){             //计算个数
                    count++;
                    ans = ans&(ans-1);
                }
                printf("%d
    ",count);
            }
        }
        return 0;
    }
  • 相关阅读:
    网页设计基础教程最最简单的一个ppt
    [转载]DIV CSS设计时IE6、IE7、FF 与兼容性有关的特性
    微软免费图书《Introducing Microsoft LINQ》翻译Chapter2.1:C# 3.0 特性(对象初始化表达式\匿名类型\查询表达式)
    asp.net3.5关于FileUpload控件的一个注意点的思考
    jQuery学习笔记:文档处理
    发布一个简单小巧的ajax操作类
    c#3.0关于JSON简单操作的实用帮助类(泛型实现)
    iBATIS.net直接执行sql语句
    c#将对象序列化为字符串和将字符串反序列化为对象
    iBATIS.net的OR映射篇
  • 原文地址:https://www.cnblogs.com/bingdada/p/7768169.html
Copyright © 2020-2023  润新知