线段树(good)Codeforces Round #275 (Div. 2)D

来源:互联网 发布:怎么样让淘宝号升心快 编辑:程序博客网 时间:2024/04/28 21:39

题意: 构造一个序列,满足m个形如:[l,r,c] 的条件。 [l,r,c]表示[l,r]中的元素按位与(&)的和为c。

解法: 线段树维护,sum[rt]表示要满足到现在为止的条件时该子树的按位与和至少为多少。

更新时,如果val的pos位为1,那么整个区间的按位与和pos位也应该为1,否则与出来就不对了。(这是本题解题的核心)

那么此时更新 sum[rt] |= val 即可。然后再check一遍看是否满足所有条件即可。

#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;const int maxn=100010;typedef long long LL;int N,M;struct node{    int l,r;    LL q;}qu[maxn];struct IntervalTree{    int sum[maxn<<2],setv[maxn<<2];    void build(int o,int l,int r)    {        sum[o]=setv[o]=0;        if(l==r)return;        int mid=(l+r)>>1;        build(o<<1,l,mid);        build(o<<1|1,mid+1,r);    }    void pushdown(int o)    {        if(setv[o])        {            setv[o<<1]|=setv[o];            setv[o<<1|1]|=setv[o];            sum[o<<1]|=setv[o];            sum[o<<1|1]|=setv[o];            setv[o]=0;        }    }    void pushup(int o)    {        sum[o]=sum[o<<1]&sum[o<<1|1];    }    void update(int o,int l,int r,int q1,int q2,int val)    {        if(q1<=l&&r<=q2)        {            sum[o]|=val;            setv[o]|=val;            return;        }        pushdown(o);        int mid=(l+r)>>1;        if(q1<=mid)update(o<<1,l,mid,q1,q2,val);        if(q2>mid)update(o<<1|1,mid+1,r,q1,q2,val);        pushup(o);    }    int query(int o,int l,int r,int q1,int q2)    {        if(q1<=l&&r<=q2)return sum[o];        pushdown(o);        int mid=(l+r)>>1;        if(q2<=mid)return query(o<<1,l,mid,q1,q2);        else if(q1>mid) return query(o<<1|1,mid+1,r,q1,q2);        else return (query(o<<1,l,mid,q1,q2)&query(o<<1|1,mid+1,r,q1,q2));    }    void print(int o,int l,int r)    {        if(l==r)        {            printf("%d ",sum[o]);            return;        }        pushdown(o);        int mid=(l+r)>>1;        print(o<<1,l,mid);        print(o<<1|1,mid+1,r);    }}tree;int main(){    while(scanf("%d%d",&N,&M)!=EOF)    {        tree.build(1,1,N);        for(int i=1;i<=M;i++)        {            scanf("%d%d%d",&qu[i].l,&qu[i].r,&qu[i].q);            tree.update(1,1,N,qu[i].l,qu[i].r,qu[i].q);        }        int flag=1;        for(int i=1;i<=M;i++)        {            if(tree.query(1,1,N,qu[i].l,qu[i].r)!=qu[i].q)            {                flag=0;                break;            }        }        if(!flag)printf("NO\n");        else {printf("YES\n");tree.print(1,1,N);printf("\n");}    }    return 0;}


0 0
原创粉丝点击