D - Interesting Array
题目大意:给出了一些区间的与值,求满足限制的一个序列。
解题思路:给了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;
}