CodeForces 482B Interesting Array

Description

We'll call an array of n non-negative integers a[1], a[2], ..., a[n]interesting, if it meets m constraints. The i-th of the m constraints consists of three integers li, ri, qi (1 ≤ li ≤ ri ≤ n) meaning that value should be equal to qi.

Your task is to find any interesting array of n elements or state that such array doesn't exist.

Expression x&y means the bitwise AND of numbers x and y. In programming languages C++, Java and Python this operation is represented as "&", in Pascal — as "and".

Input

The first line contains two integers n, m (1 ≤ n ≤ 105, 1 ≤ m ≤ 105) — the number of elements in the array and the number of limits.

Each of the next m lines contains three integers li, ri, qi (1 ≤ li ≤ ri ≤ n, 0 ≤ qi < 230) describing the i-th limit.

Output

If the interesting array exists, in the first line print "YES" (without the quotes) and in the second line print n integers a[1], a[2], ..., a[n] (0 ≤ a[i] < 230) decribing the interesting array. If there are multiple answers, print any of them.

If the interesting array doesn't exist, print "NO" (without the quotes) in the single line.

Sample Input

Input
3 1
1 3 3
Output
YES
3 3 3
Input
3 2
1 3 3
1 3 2
Output
NO


/**
    题意:给n个数和m个操作,每个操作形如: l r x, 表示a[l] & a[l+1] & ... &a[r] = x;
                问:是否存在这样一个序列满足所给操作?
                    有:输出YES,并输出这个序列。
                没有:输出NO。
    分析:考虑a[i],对于所有包含它的操作,如果取与操作后为x,
                则x的二进制为1的位上,a[i]也为1。
                其他位都为0肯定是满足的。
                那么我们可以对所有x取或,得到的就是a[i]。
                线段树区间操作就不多说了。
                最后,检验序列是否符合要求。
   */
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
const int N = 100001;
int ans[N],mak[N<<2];
int ql[N],qr[N],qx[N];
void pushdown(int rt)
{
    if(!mak[rt]) return ;
    mak[rt<<1]|=mak[rt];
    mak[rt<<1|1]|=mak[rt];
    mak[rt] = 0;
}
void update(int L, int R, int x, int l, int r, int rt)
{
    if(L<=l && R>=r)
    {
        mak[rt]|=x;
        return;
    }
    int m = l+r>>1;
    if(L<=m) update(L,R,x,l,m,rt<<1);
    if(R>m)   update(L,R,x,m+1,r,rt<<1|1);
}
void solve(int l, int r, int rt)
{
    if(l==r)
    {
        ans[l] = mak[rt];
        return ;
    }
    int m = l+r>>1;
    pushdown(rt);
    solve(l,m,rt<<1);
    solve(m+1,r,rt<<1|1);
}
void build(int l, int r, int rt)
{
    if(l==r)
    {
        mak[rt] = ans[l];
        return ;
    }
    int m = l+r>>1;
    build(l,m,rt<<1);
    build(m+1,r,rt<<1|1);
    mak[rt] = mak[rt<<1]&mak[rt<<1|1];
}
int query(int L, int R, int l, int r, int rt)
{
    if(L<=l && R>=r) return mak[rt];
    int m = l+r>>1;
    int s = (1<<30)-1;
    if(L<=m) s&=query(L,R,l,m,rt<<1);
    if(R>m)   s&=query(L,R,m+1,r,rt<<1|1);
    return s;
}
int main()
{
    int i,j,k,m,n;
    while(scanf("%d %d",&n,&m)==2)
    {
        memset(mak,0,sizeof(mak));
        for(i=1; i<=m; i++)
        {
            scanf("%d%d%d",ql+i,qr+i,qx+i);
            update(ql[i],qr[i],qx[i],1,n,1);
        }
        solve(1,n,1);
        build(1,n,1);
        bool ok = true;
        for(i=1; i<=m; i++)
        {
            int a = query(ql[i],qr[i],1,n,1);
            if(a!=qx[i])
            {
                ok = false;
                break;
            }
        }
        if(!ok)
        {
            puts("NO");
            continue;
        };
        puts("YES");
        for(i=1; i<n; i++) printf("%d ",ans[i]);
        printf("%d\n",ans[n]);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值