CF 483D Interesting Array(线段树)

D. Interesting Array
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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 liriqi (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 nm (1 ≤ n ≤ 1051 ≤ m ≤ 105) — the number of elements in the array and the number of limits.

Each of the next m lines contains three integers liriqi (1 ≤ li ≤ ri ≤ n0 ≤ 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.

Examples
input
Copy
3 1
1 3 3
output
Copy
YES
3 3 3
input
Copy
3 2
1 3 3
1 3 2
output
Copy
NO

题意:

构造出一个序列,满足下面m个要求:

每一个要求的组成是l,r,q三个数,表示从a[l]&a[l+1]....&a[r]的值为q,问能不能构造出这样的序列。

思路:

sum[i]表示该区间的&的值,一开始处理每个要求的时候,我们都让它直接满足该要求,sum[i]|q来满足。最后我们再看看每个sum[i]的值是否还为原来的值,如果不是,则无法构造。可以的话,那么我们查询到叶子节点就是构造的序列。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1e5+5;
int sum[maxn<<2],lazy[maxn<<2];
int l[maxn],r[maxn],c[maxn];
int now;
void pushdown(int i)
{
    if(lazy[i])
    {
        sum[2*i]|=lazy[i];
        sum[2*i+1]|=lazy[i];
        lazy[2*i]|=lazy[i];
        lazy[2*i+1]|=lazy[i];
        lazy[i]=0;
    }
}
void update(int i,int l,int r,int x,int y,int c)
{
    if(x<=l&&r<=y)
    {
        sum[i]|=c;
        lazy[i]|=c;
        return;
    }
    pushdown(i);
    int mid=(l+r)/2;
    if(x<=mid) update(2*i,l,mid,x,y,c);
    if(y>mid) update(2*i+1,mid+1,r,x,y,c);
    sum[i]=sum[2*i]&sum[2*i+1];
    return;
}
void query(int i,int l,int r,int x,int y)
{
    if(x<=l&&r<=y)
    {
        now&=sum[i];
        return;
    }
    pushdown(i);
    int mid=(l+r)/2;
    if(x<=mid) query(2*i,l,mid,x,y);
    if(y>mid) query(2*i+1,mid+1,r,x,y);
    sum[i]=sum[2*i]&sum[2*i+1];
    return;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&l[i],&r[i],&c[i]);
            update(1,1,n,l[i],r[i],c[i]);
        }
        for(int i=1;i<=m;i++)
        {
            now=(1<<30)-1;
            query(1,1,n,l[i],r[i]);
            if(now!=c[i])
            {
                cout<<"NO"<<endl;
                return 0;
            }
        }
        cout<<"YES"<<endl;
        for(int i=1;i<=n;i++)
        {
            now=(1<<30)-1;
            query(1,1,n,i,i);
            cout<<now<<" ";
        }
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/timeclimber/article/details/80940279