• 牛客网-湘潭大学校赛重现H题 (线段树 染色问题)


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

    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

    思路:
    看到颜色<=60,摆明了用二进制。。写法跟poj2777差不多,只不过poj2777是覆盖颜色,这个是增加颜色。。
    忘了 << 运算不支持long long范围。。找了半天错。。。直接用快速幂代替就好了
    如果之前写过这种类型的题的话写起来就很简单了.

    实现代码;
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<string>
    #include<cmath>
    using namespace std;
    #define ll long long
    const ll M = 1e5+10;
    ll powl(ll n,ll m)
    {
        ll ans = 1;
        while(m > 0)
        {
            if(m & 1)ans = (ans * n);
            m = m >> 1;
            n = (n * n);
        }
        return ans;
    }
    
    ll n,w,e;
    ll color[M*4],lazy[M*4];
    void pushup(ll rt){
       color[rt] = color[rt*2]|color[rt*2+1];
    }
    
    void build(ll l,ll r,ll rt){
        if(l==r){
            color[rt] = 0;
            return ;
        }
        ll m = (l+r)/2;
        build(l,m,rt*2);
        build(m+1,r,rt*2+1);
        pushup(rt);
    }
    
    void pushdown(ll rt){
        if(lazy[rt]){
            lazy[rt*2] |= lazy[rt];
            lazy[rt*2+1] |= lazy[rt];
            color[rt*2] |= lazy[rt*2];
            color[rt*2+1] |= lazy[rt*2+1];
            lazy[rt] = 0;
        }
    }
    
    void update(ll L,ll R,ll l,ll r,ll x,ll rt){
         if(L<=l&&r<=R){
            lazy[rt] |= powl(2,x-1);
            color[rt] |= powl(2,x-1);
            return ;
         }
         pushdown(rt);
         ll m = (l+r)/2;
         if(L<=m)  update(L,R,l,m,x,rt*2);
         if(R>m) update(L,R,m+1,r,x,rt*2+1);
         pushup(rt);
    }
    
    ll query(ll L,ll R,ll l,ll r,ll rt){
        if(L<=l&&r<=R){
            return color[rt];
        }
        ll ans1=0,ans2=0,ans;
        ll m = (l+r)/2;
        pushdown(rt);
        if(L<=m) ans1+=query(L,R,l,m,rt*2);
        if(R>m)  ans2+=query(L,R,m+1,r,rt*2+1);
        ans = ans1|ans2;
        return ans;
    }
    
    void getsum(ll x){
        ll ans = 0;
        while(x){
            if(x%2==1) ans++;
            x/=2;
        }
        printf("%lld
    ",ans);
    }
    
    int main()
    {
        ll L,R,x;
        int c;
        while(scanf("%lld%lld",&n,&w)!=EOF){
            memset(lazy,0,sizeof(lazy));
            build(1,n,1);
            while(w--){
            scanf("%lld",&c);
            if(c==1){
                scanf("%lld%lld%lld",&L,&R,&x);
                if(L>R) swap(L,R);
                x++;
                update(L,R,1,n,x,1);
            }
            else{
                scanf("%lld%lld",&L,&R);
                if(L>R) swap(L,R);
                ll cnt = query(L,R,1,n,1);
                 //cout<<cnt<<endl;
                getsum(cnt);
            }
        }
        }
        return 0;
    }
  • 相关阅读:
    CSS盒模型
    js异步加载——defer和async的区别
    href和src的区别
    JS中Null与Undefined的区别
    浅谈Web Workers
    flex布局学习笔记
    Promise
    js数组类型检测
    JavaScript中的遍历
    Autocomplete
  • 原文地址:https://www.cnblogs.com/kls123/p/8955346.html
Copyright © 2020-2023  润新知