解题报告: 这题看着别人板子写的,竟然是线段树,真没看出来Orz,思路就是我们通过m次操作,建立线段树,并且每次给区间l,r 或上一个d值,最后检查每次询问的范围内想与的值还是不是原来的值,如果不是就输出no
#include<iostream> #include<cstring> #include<vector> #include<algorithm> #include<map> #include<set> #include<cmath> using namespace std; typedef long long ll; const int N=100010; const int mod=1e9+7; struct node{ int l; int r; int val; int tag; }tr[N<<2]; void pushup(int u) { tr[u].val=tr[u<<1].val&tr[u<<1|1].val; } void pushdown(int u) { tr[u<<1].val|=tr[u].tag; tr[u<<1].tag|=tr[u].tag; tr[u<<1|1].val|=tr[u].tag; tr[u<<1|1].tag|=tr[u].tag; tr[u].tag=0; } int n,m; void build(int u,int l,int r) { tr[u].l=l,tr[u].r=r; if(l==r) return ; int mid = l+r>>1; build(u<<1,l,mid),build(u<<1|1,mid+1,r); } void modify(int u,int l,int r,int d) { if(tr[u].l>=l&&tr[u].r<=r) { tr[u].val|=d; tr[u].tag|=d; return ; } pushdown(u); int mid=tr[u].l+tr[u].r>>1; if(l<=mid) modify(u<<1,l,r,d); if(r>mid) modify(u<<1|1,l,r,d); pushup(u); } int query(int u,int l,int r) { if(tr[u].l>=l && tr[u].r<=r) return tr[u].val; pushdown(u); int res=(1<<30)-1; int mid=tr[u].l+tr[u].r>>1; if(l<=mid) res&=query(u<<1,l,r); if(r>mid) res&=query(u<<1|1,l,r); pushup(u); return res; } struct nn{ int l; int r; int d; }q[1000010]; int main() { cin >> n >> m; build(1,1,n); for(int i=0;i<m;i++) { cin >> q[i].l >> q[i].r >> q[i].d; if(q[i].l>q[i].r) swap(q[i].l,q[i].r); modify(1,q[i].l,q[i].r,q[i].d); } bool flag=true; for(int i=0;i<m;i++) { if(query(1,q[i].l,q[i].r)!=q[i].d) { flag=false; break; } } if(!flag) cout<<"NO"<<endl; else { cout<<"YES"<<endl; for(int i=1;i<=n;i++) cout<<query(1,i,i)<<' '; cout<<endl; } return 0; }