• noip模拟赛 fateice-or


     

    分析:or操作只有在结果的这一位为0的情况下才会强制要求两个数的这一位都为0,其它时候不强求,所以为了最大限度地满足条件,我们先把所有的数的所有位全部变成1,如果p的第i位为0,那么[l,r]的数的第i位都要为0,&一下p就好了.最后检验一下看看是否满足所有条件就可以了。为什么这样做事合法的呢?因为我们之前已经尽可能让它最大限度地满足条件了,某一位更改后可能就不能满足这么多条件了,如果这都不行,那么肯定无解.因为是区间&操作,所以用线段树来优化.

    构造题要满足所有的条件,那么就构造出尽可能多地满足条件的,最后检验一下就可以了.

        注意:实际操作是|,但是每次进行的操作是&,在合并和修改的时候不要弄混了.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int inf = (1 << 30) - 1, maxn = 300010;
    
    int n, m, l[maxn], r[maxn], p[maxn], v[maxn * 4], tag[maxn * 4], flag[maxn * 4];
    bool can = true;
    
    void build(int o, int l, int r)
    {
        tag[o] = v[o] = inf;
        if (l == r)
            return;
        int mid = (l + r) >> 1;
        build(o * 2, l, mid);
        build(o * 2 + 1, mid + 1, r);
    }
    
    void pushup(int o)
    {
        v[o] = v[o * 2] | v[o * 2 + 1];
    }
    
    void pushdown(int o)
    {
        if (flag[o])
        {
            flag[o * 2] = flag[o * 2 + 1] = 1;
            flag[o] = 0;
            tag[o * 2] &= tag[o];
            tag[o * 2 + 1] &= tag[o];
            v[o * 2] &= tag[o];
            v[o * 2 + 1] &= tag[o];
            tag[o] = inf;
        }
    }
    
    void update(int o, int l, int r, int x, int y, int c)
    {
        if (x <= l && r <= y)
        {
            tag[o] &= c;
            v[o] &= c;
            flag[o] = 1;
            return;
        }
        pushdown(o);
        int mid = (l + r) >> 1;
        if (x <= mid)
            update(o * 2, l, mid, x, y, c); 
        if (y > mid)
            update(o * 2 + 1, mid + 1, r, x, y, c);
        pushup(o);
    }
    
    int query(int o, int l, int r, int x, int y)
    {
        if (x <= l && r <= y)
            return v[o];
        pushdown(o);
        int mid = (l + r) >> 1, res = 0;
        if (x <= mid)
            res |= query(o * 2, l, mid, x, y); 
        if (y > mid)
            res |= query(o * 2 + 1, mid + 1, r, x, y);
        return res;
    }
    
    int main()
    {
        freopen("or1.in", "r", stdin);
        freopen("or2.txt", "w", stdout);
        scanf("%d%d", &n, &m);
        build(1, 1, n);
        for (int i = 1; i <= m; i++)
        {
            scanf("%d%d%d", &l[i], &r[i], &p[i]);
            update(1, 1, n, l[i], r[i], p[i]);
        }
        for (int i = 1; i <= m; i++)
            if (query(1, 1, n, l[i], r[i]) != p[i])
            {
                can = 0;
                break;
            }
        if (can == false)
            printf("No
    ");
        else
        {
            printf("Yes
    ");
            for (int i = 1; i <= n; i++)
                printf("%d ",query(1,1,n,i,i));
        }
    
        return 0;
    }
  • 相关阅读:
    COM组件
    【游戏引擎架构】入门(一)
    UNICODE字符串
    Python随笔10
    Python随笔9-函数
    Python随笔7
    Python随笔6
    Python随笔5
    Python随笔4
    Python随笔3
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7674427.html
Copyright © 2020-2023  润新知