解题报告:
这题看着别人板子写的,竟然是线段树,真没看出来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;
}