题意:构造一个长度为n的序列,使其满足m个形式如下如下约束:a[l]&a[l+1]&a[l+2]&....&a[r]=q
从Dalao的博客上看到这题,决定去水水。做法比较显然,就是做一些区间or之后判断一下之前的条件是否满足。用线段树维护即可。
不出意外,我的线段树又调爆了,因为我把<<打成了>>。。。。
#include<bits/stdc++.h>
using namespace std;
#define MAXN 1000000+10
struct tree{int sum,tag;}tr[MAXN*];
int n,m,l[MAXN],r[MAXN],q[MAXN];
void pushup(int k){tr[k].sum=tr[k<<].sum&tr[k<<|].sum;}
void pushdown(int k){
if(!tr[k].tag)return;
tr[k<<].sum|=tr[k].tag;
tr[k<<|].sum|=tr[k].tag;
tr[k<<].tag|=tr[k].tag;
tr[k<<|].tag|=tr[k].tag;
tr[k].tag=;
}
void build(int k,int l,int r){
tr[k].tag=;
if(l==r){
tr[k].sum=;
return;
}
int mid=(l+r)>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
pushup(k);
}
void update(int k,int l,int r,int L,int R,int t){
if(l>=L&&r<=R){
tr[k].sum|=t;
tr[k].tag|=t;
return;
}
pushdown(k);
int mid=(l+r)>>;
if(R<=mid)update(k<<,l,mid,L,R,t);
else if(L>mid)update(k<<|,mid+,r,L,R,t);
else update(k<<,l,mid,L,R,t),update(k<<|,mid+,r,L,R,t);
pushup(k);
}
int query(int k,int l,int r,int L,int R){
if(l>=L&&r<=R)return tr[k].sum;
pushdown(k);
int mid=(l+r)>>;
if(R<=mid)return query(k<<,l,mid,L,R);
else if(L>mid)return query(k<<|,mid+,r,L,R);
else return query(k<<,l,mid,L,R)&query(k<<|,mid+,r,L,R);
pushup(k);
}
int main(){
//freopen("data.in","r",stdin);
scanf("%d%d",&n,&m);
build(,,n);
for(int i=;i<=m;i++){
scanf("%d%d%d",&l[i],&r[i],&q[i]);
update(,,n,l[i],r[i],q[i]);
}
for(int i=;i<=m;i++){
int t=query(,,n,l[i],r[i]);
if(t!=q[i]){
puts("NO");
return ;
}
}
printf("YES\n");
for(int i=;i<=n;i++)printf("%d ",query(,,n,i,i));
return ;
}