zoukankan      html  css  js  c++  java
  • Codeforces482B【线段树构造】

    题意:
    有M个限制,每个限制有l,r,q,表示从a[l]~a[r]取且后的数一定为q,问是否有满足的数列。
    思路:
    看到大牛说是线段树,线段树对于区间操作,印象中乘啊,+啊,-啊都不错,但是并没有就是对于这个位运算就不懂了;
    这题的题意就是构造,大致思路是
    每条限制是对于每个区间处理就是或上q(可以保证相应的二进制一定是1),然后用线段树处理完m个限制,最后还要询问一下m个限制是否满足;
    所以具体操作就是利用线段树进行区间或操作,区间查询且。
    PS:
    在最后取n个数的时候撒比了,直接取了树上的n个节点位置的数,= =、q[num].x和当left==right的num完全不一样的啊。。哎真踏马蠢了。。
    code…

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    
    const int N=1e5+10;
    struct asd{
        int left,right;
        int x;
    };
    asd q[N*4];
    
    struct nod{
        int a,b,c;
    };
    nod temp[N];
    
    void build(int num,int L,int R)
    {
        q[num].left=L;
        q[num].right=R;
        if(L==R)
        {
            q[num].x=0;
            return;
        }
        build(2*num,L,(L+R)/2);
        build(2*num+1,(L+R)/2+1,R);
        q[num].x=q[2*num].x^q[2*num+1].x;
    }
    
    void update(int num,int s,int t,int c)
    {
        if(s<=q[num].left&&t>=q[num].right)
        {
            q[num].x|=c;
            return;
        }
        int mid=(q[num].left+q[num].right)/2;
        if(mid>=t)
            update(2*num,s,t,c);
        else if(mid<s)
            update(2*num+1,s,t,c);
        else
        {
            update(2*num,s,mid,c);
            update(2*num+1,mid+1,t,c);
        }
    }
    int query(int num,int s,int t)
    {
        if(s<=q[num].left&&t>=q[num].right)
            return q[num].x;
        int mid=(q[num].left+q[num].right)/2;
        if(mid>=t)
            return query(2*num,s,t);
        else if(mid<s)
            return query(2*num+1,s,t);
        else
        {
            return query(2*num,s,mid)&query(2*num+1,mid+1,t);
        }
    }
    
    vector<int>ans;
    void solve(int num)
    {
        if(num!=1)
        {
            q[num].x|=q[num/2].x;
        }
        if(q[num].left==q[num].right)
        {
            ans.push_back(q[num].x);
            return;
        }
        solve(2*num);
        solve(2*num+1);
    }
    
    int main()
    {
        int a,b,c;
        int n,m;
        scanf("%d%d",&n,&m);
        build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            update(1,a,b,c);
            temp[i].a=a;
            temp[i].b=b;
            temp[i].c=c;
        }
        bool flag=true;
        for(int i=1;i<=m;i++)
        {
            if(query(1,temp[i].a,temp[i].b)!=temp[i].c)
            {
                flag=false;
                break;
            }
        }
        solve(1);
        if(flag)
        {
            puts("YES");
            printf("%d",q[1].x);//我直接for一下输出和下面的在vector里面输出为啥顺序不一样。。废话。。踏马这个num是最终子节点么,卧槽。。
            for(int i=2;i<=n;i++)
            {
                printf(" %d",q[i].x);
            }
    
            printf("%d",ans[0]);
            for(int i=1;i<ans.size();i++)
            {
                printf(" %d",ans[i]);
            }
        }
        else
            puts("NO");
        return 0;
    }
  • 相关阅读:
    js-计算器
    正确看待HTML5的语法变化
    什么是Web前端,Web前端是做什么的?
    css复合属性的写法
    Unicode与JavaScript详解
    input 定宽,文本超出后缩小字体,尽可能多的显示文本
    手机号中间四位加*号
    React 状态和生命周期
    还是数组 练习题 而已
    数组 练习题 而已
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934796.html
Copyright © 2011-2022 走看看