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