• 统计颜色~线段树


    链接:https://www.nowcoder.com/acm/contest/105/H
    来源:牛客网

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 32768K,其他语言65536K
    64bit IO Format: %lld

    题目描述

    n个桶按顺序排列,我们用1~n给桶标号。有两种操作:
    1 l r c 区间[l,r]中的每个桶中都放入一个颜色为c的球 (1≤l,r ≤n,l≤r,0≤c≤60)
    2 l r   查询区间[l,r]的桶中有多少种不同颜色的球     (1≤l,r ≤n,l≤r)

    输入描述:

    有多组数据,对于每组数据:
    第一行有两个整数n,m(1≤n,m≤100000)
    接下来m行,代表m个操作,格式如题目所示。

    输出描述:

    对于每个2号操作,输出一个整数,表示查询的结果。
    示例1

    输入

    10 10
    1 1 2 0
    1 3 4 1
    2 1 4
    1 5 6 2
    2 1 6
    1 7 8 1
    2 3 8
    1 8 10 3
    2 1 10
    2 3 8

    输出

    2
    3
    2
    4
    3

    这题是线段树裸题 ,用位运算处理很方便

      按位或运算符(|)

      参加运算的两个对象,按二进制位进行“或”运算。

      运算规则:0|0=0;  0|1=1;  1|0=1;   1|1=1;

      即 :参加运算的两个对象只要有一个为1,其值为1。



    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    using namespace std;
    const int maxn = 1e5 + 10;
    
    typedef long long LL ;
    LL add[maxn << 2], sum[maxn << 2];
    void pushup(LL rt) {
        sum[rt] = sum[rt << 1] | sum[rt << 1 | 1];
    }
    void pushdown(LL rt) {
        if (add[rt]) {
            add[rt << 1] |= add[rt];
            add[rt << 1 | 1] |= add[rt];
            sum[rt << 1] |= add[rt];
            sum[rt << 1 | 1] |= add[rt];
            add[rt] = 0;
        }
    }
    void updata(LL x, LL y, LL z, LL l, LL r, LL rt) {
        if (r<x || l>y ) return ;
        if (x <= l && r <= y) {
            sum[rt] |= z;
            add[rt] |= z;
            return ;
        }
        pushdown(rt);
        LL m = (l + r) >> 1;
        updata(x, y, z, l, m, rt << 1);
        updata(x, y, z, m + 1, r, rt << 1 | 1);
        pushup(rt);
    }
    LL query(LL x, LL y, LL l, LL r, LL rt ) {
        if (x <= l && r <= y) return sum[rt];
        pushdown(rt);
        LL ans = 0;
        LL mid = (l + r) >> 1;
        if (y > mid) ans |= query(x, y, mid + 1, r, rt << 1 | 1);
        if (x <= mid) ans |= query(x, y, l, mid, rt << 1);
        return ans;
    }
    LL getx(LL x) {
        LL ans = 0;
        while(x) {
            ans += x % 2;
            x /= 2;
        }
        return ans;
    }
    int main() {
        LL n, m;
        //freopen("DATA.txt", "r", stdin);
        while(scanf("%lld%lld", &n, &m) != EOF) {
            memset(sum, 0, sizeof(sum));
            memset(add, 0, sizeof(add));
            while(m--) {
                LL l, r, x;
                scanf("%lld", &x);
                scanf("%lld%lld", &l, &r);
                if(x == 1) {
                    LL a;
                    scanf("%lld", &a);
                    updata(l, r, (LL)1 << a, 1, n, 1 );
                } else {
                    LL t = query(l, r, 1, n, 1);
                    printf("%lld
    ", getx(t));
                }
            }
        }
        return 0;
    }


  • 相关阅读:
    【转载】JS中bind方法与函数柯里化
    计算机中位(bit), 字节(byte), 字(word)的关系
    MySQL 正则(Regular Expression) 邮箱(Email)
    eclipse remote system explorer operation
    Hibernate save, saveOrUpdate, persist, merge, update 区别
    产品经理 写SQL
    DevOps Scrum Agile Tech Debt
    SpringMVC 集成 jackson,日志格式报错:org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.util.Date from String value
    EDAS Serverless & Kubernetes SLB LVS Nginx
    阿里巴巴 开发者 工具 开源 社区
  • 原文地址:https://www.cnblogs.com/qldabiaoge/p/8972075.html
Copyright © 2020-2023  润新知