题意:
给n和m
和m个l,r,x
要求构造一个数组,使得对于m个条件l,r,x
[l,r]的区间与(&)结果为x
思路:
对于每个l,r,x
如果x的某一位为1,则[l,r]中每一位的这个位置都要为1
所以直接对区间[l,r]的这一位赋值为1
m次操作结束之后再对m个操作判断区间[l,r]的区间与是否等于x就行了
如果不等于则说明条件中有互相冲突的,则无解
区间操作用线段树实现
code:
#include<bits/stdc++.h>
using namespace std;
const int maxm=1e5+5;
int a[maxm<<2];
int laz[maxm<<2];
struct Q{
int l,r,x;
}q[maxm];
void pushdown(int node){
if(laz[node]){
int lz=laz[node];
a[node*2]|=lz;
a[node*2+1]|=lz;
laz[node*2]|=lz;
laz[node*2+1]|=lz;
laz[node]=0;
}
}
void pushup(int node){
a[node]=(a[node*2]&a[node*2+1]);
}
void update(int st,int ed,int val,int l,int r,int node){
if(st<=l&&ed>=r){
a[node]|=val;
laz[node]|=val;
return ;
}
pushdown(node);
int mid=(l+r)/2;
if(st<=mid){
update(st,ed,val,l,mid,node*2);
}
if(ed>=mid+1){
update(st,ed,val,mid+1,r,node*2+1);
}
pushup(node);
}
int ask(int st,int ed,int l,int r,int node){
if(st<=l&&ed>=r){
return a[node];
}
pushdown(node);
int mid=(l+r)/2;
int ans=(1<<30)-1;//全1
if(st<=mid){
ans&=ask(st,ed,l,mid,node*2);
}
if(ed>=mid+1){
ans&=ask(st,ed,mid+1,r,node*2+1);
}
pushup(node);
return ans;
}
signed main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++){
int l,r,x;
cin>>l>>r>>x;
update(l,r,x,1,n,1);
q[i]={l,r,x};
}
for(int i=1;i<=m;i++){
int l=q[i].l,r=q[i].r;
int x=q[i].x;
if(ask(l,r,1,n,1)!=x){//如果不满足直接no
cout<<"NO"<<endl;
return 0;
}
}
cout<<"YES"<<endl;
for(int i=1;i<=n;i++){//输出每一个
cout<<ask(i,i,1,n,1)<<' ';
}
cout<<endl;
return 0;
}