CodeForces - 483D Interesting Array (线段树)

D - Interesting Array

 CodeForces - 483D 

题目大意:给出了一些区间的与值,求满足限制的一个序列。

解题思路:给了m个区间的与值v,相当于如果v的某一个位置的值为1,那么区间里的这些数的这个位置也要为1,因此我们可以用|运算来向下传递标记,如果某个点上有若干个区间,每个这个点的值就是这些值的或值。把所有的限制条件加入后再检查一遍即可。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define sca(x) scanf("%d",&x)
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define N 100005
#define inf 0x3f3f3f3f
#define pb(x) push_back(x)

struct node
{
    int x,y,z;
}a[N];

int sum[N*4],lazy[N*4];

void push_down(int rt)
{
    if(lazy[rt])
    {
        sum[rt<<1] |= lazy[rt];
        sum[rt<<1|1] |= lazy[rt];
        lazy[rt<<1] |= lazy[rt];
        lazy[rt<<1|1] |= lazy[rt];
        lazy[rt]=0;
    }
}

void push_up(int rt)
{
    sum[rt]=sum[rt<<1]&sum[rt<<1|1];
}

void upda(int rt,int l,int r,int ql,int qr,int val)
{
    if(l>=ql&&r<=qr)
    {
        sum[rt] |= val;
        lazy[rt] |= val;
        return ;
    }
    push_down(rt);
    int m=(l+r)>>1;
    if(ql<=m)upda(rt<<1,l,m,ql,qr,val);
    if(qr>m)upda(rt<<1|1,m+1,r,ql,qr,val);
    push_up(rt);
}

int ask(int rt,int l,int r,int ql,int qr)
{
    if(l>=ql&&r<=qr)return sum[rt];
    int ans=(1LL<<32)-1;
    push_down(rt);
    int m=(l+r)>>1;
    if(ql<=m)ans &= ask(rt<<1,l,m,ql,qr);
    if(qr>m) ans &= ask(rt<<1|1,m+1,r,ql,qr);
    push_up(rt);
    return ans;
}

void Pri(int rt,int l,int r,int n)
{
    if(l==r)
    {
        printf("%d%c",sum[rt],l==n?'\n':' ');
        return ;
    }
    push_down(rt);
    int m=(l+r)>>1;
    Pri(rt<<1,l,m,n);
    Pri(rt<<1|1,m+1,r,n);
    push_up(rt);
}

int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    }
    for(int i=1;i<=m;i++){
        upda(1,1,n,a[i].x,a[i].y,a[i].z);
    }
    for(int i=1;i<=m;i++){
        if(a[i].z!=ask(1,1,n,a[i].x,a[i].y)){
            puts("NO");
            return 0;
        }
    }
    puts("YES");
    Pri(1,1,n,n);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_40894017/article/details/88421287
今日推荐