题意:构造一个长度为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*8]; int n,m,l[MAXN],r[MAXN],q[MAXN]; void pushup(int k){tr[k].sum=tr[k<<1].sum&tr[k<<1|1].sum;} void pushdown(int k){ if(!tr[k].tag)return; tr[k<<1].sum|=tr[k].tag; tr[k<<1|1].sum|=tr[k].tag; tr[k<<1].tag|=tr[k].tag; tr[k<<1|1].tag|=tr[k].tag; tr[k].tag=0; } void build(int k,int l,int r){ tr[k].tag=0; if(l==r){ tr[k].sum=0; return; } int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,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)>>1; if(R<=mid)update(k<<1,l,mid,L,R,t); else if(L>mid)update(k<<1|1,mid+1,r,L,R,t); else update(k<<1,l,mid,L,R,t),update(k<<1|1,mid+1,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)>>1; if(R<=mid)return query(k<<1,l,mid,L,R); else if(L>mid)return query(k<<1|1,mid+1,r,L,R); else return query(k<<1,l,mid,L,R)&query(k<<1|1,mid+1,r,L,R); pushup(k); } int main(){ //freopen("data.in","r",stdin); scanf("%d%d",&n,&m); build(1,1,n); for(int i=1;i<=m;i++){ scanf("%d%d%d",&l[i],&r[i],&q[i]); update(1,1,n,l[i],r[i],q[i]); } for(int i=1;i<=m;i++){ int t=query(1,1,n,l[i],r[i]); if(t!=q[i]){ puts("NO"); return 0; } } printf("YES "); for(int i=1;i<=n;i++)printf("%d ",query(1,1,n,i,i)); return 0; }