We'll call an array of n non-negative integersa[1], a[2], ..., a[n]interesting, if it meets m constraints. The i-th of them constraints consists of three integersli,ri,qi (1 ≤ li ≤ ri ≤ n) meaning that value should be equal toqi.
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 numbersx andy. In programming languages C++, Java and Python this operation is represented as "&", in Pascal — as "and".
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 integersli,ri,qi (1 ≤ li ≤ ri ≤ n,0 ≤ qi < 230) describing thei-th limit.
If the interesting array exists, in the first line print "YES" (without the quotes) and in the second line printn integersa[1], a[2], ..., a[n] (0 ≤ a[i] < 230) decribing theinteresting 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.
3 1
1 3 3
YES
3 3 3
3 2
1 3 3
1 3 2
NO
题目链接 :http://codeforces.com/contest/483/problem/D
题目大意 :输入n个数的序列,有m组(m个限制),要求求一组序列满足该序列的l位置到r位置的值的与等于q,若不存在输出No
,
题目分析 :线段树维护,判a[l]&a[l+1]&...&a[r]的值是否等于q,要满足这样的条件,我们可以用q去和每个节点取或运算,因为每个节点在一起的与值是固定的等于q 比如 q = 3 = 111(2),节点初始化为0要满足上述条件,则要用111 | 000得到每个节点的值,算出来为111(2) = 3.
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
int const MAX = 110000;
struct Node
{
int l, r;
int val;
};
Node tree[10 * MAX];
Node a[MAX];
vector<int> ans;
void build(int step, int l, int r)
{
tree[step].l = l;
tree[step].r = r;
tree[step].val = 0;
if(l == r)
return;
int mid = (l + r) >> 1;
build(step << 1, l, mid);
build(((step << 1) + 1), mid+1, r);
}
void update(int step, int l, int r, int val)
{
if(tree[step].l == l && tree[step].r == r)
{
tree[step].val |= val;
return;
}
int mid = (tree[step].l + tree[step].r) >> 1;
if(r <= mid)
update(step << 1, l, r, val);
else if(l > mid)
update((step << 1) + 1, l, r, val);
else
{
update(step << 1, l, mid, val);
update((step << 1) + 1, mid+1, r, val);
}
}
int query(int step, int l, int r)
{
if(tree[step].l == l && tree[step].r == r)
return tree[step].val;
int mid = (tree[step].l + tree[step].r) >> 1;
if(r <= mid)
return query(step << 1, l, r);
if(l > mid)
return query((step << 1) + 1, l, r);
else
return query(step << 1, l, mid) & query((step << 1) + 1, mid+1, r);
}
void solve(int step)
{
if(step != 1)
tree[step].val |= tree[step >> 1].val;
if(tree[step].l == tree[step].r)
{
ans.push_back(tree[step].val);
return;
}
solve(step << 1);
solve((step << 1) + 1);
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
build(1, 1, n);
for(int i = 0; i < m; i++)
{
scanf("%d %d %d", &a[i].l, &a[i].r, &a[i].val);
update(1, a[i].l, a[i].r, a[i].val);
}
bool flag = true;
for(int i = 0; i < m; i++)
{
if(query(1, a[i].l, a[i].r) != a[i].val)
{
flag = false;
break;
}
}
if(flag)
{
solve(1);
printf("YES\n");
for(int i = 0; i < ans.size(); i++)
printf("%d%c",ans[i], i == n ? '\n' : ' ');
ans.clear();
printf("\n");
}
else
printf("NO\n");
}