zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    IIS7中的几种身份鉴别方式(一)Basic身份验证
    IIS7中的几种身份鉴别方式(二)集成身份验证
    java集合
    SharePoint 2010中welcome page的设置细节
    SharePoint中使用Linq出现未将对象引用到实例化的解决方法
    SharePoint 2010中关于An error was encountered while retrieving the user profile的处理方式记录
    The Need for an Architectural Body of Knowledge
    The Softer Side of the Architect
    Event Receivers 学习小结
    使用SmtpClient发送带图片的邮件的代码实现
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7674427.html
Copyright © 2011-2022 走看看