题意:m个约束条件,[l,r,v]表示区间[l,r]的数bitwise与运算的结果要等于v.
n,m<=1e5,a[i]<=1e9.问是否能构成出满足m个约束条件的序列a,若能输出方案,否则输出-1.
v二进制中为1的位,a[l]..a[r]中也都为1,v中二进制为0的位,[l,r]中我们可以不去考虑,和条件无关呀.
先满足必要条件,利用差分,将[l,r]的第 bit位设置为1.然后在用线段树判断是否满足约束条件,
n,m<=1e5,a[i]<=1e9.问是否能构成出满足m个约束条件的序列a,若能输出方案,否则输出-1.
v二进制中为1的位,a[l]..a[r]中也都为1,v中二进制为0的位,[l,r]中我们可以不去考虑,和条件无关呀.
先满足必要条件,利用差分,将[l,r]的第 bit位设置为1.然后在用线段树判断是否满足约束条件,
如果不满足则无解,因为已经为1的位是固定,在怎么变动其它位也是无解的.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+20;
ll n,m,a[N][35],b[N];
ll l[N],r[N],q[N];
struct node{
int l,r;
ll sum;
}t[N<<2];
void push_up(int o)
{
t[o].sum=t[o<<1].sum & t[o<<1|1].sum;
}
void build(int o,int l,int r)
{
t[o].l=l,t[o].r=r;
if(l==r)
{
t[o].sum=b[l];
return;
}
int m=l+r>>1;
build(o<<1,l,m);
build(o<<1|1,m+1,r);
push_up(o);
}
ll query(int o,int ql,int qr)
{
int l=t[o].l,r=t[o].r;
if(ql<=l&&qr>=r)
return t[o].sum;
int m=l+r>>1;
ll res=(1ll<<32)-1;
if(ql<=m)
res=res&query(o<<1,ql,qr);
if(qr>m)
res=res&query(o<<1|1,ql,qr);
return res;
}
int main()
{
scanf("%I64d%I64d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%I64d%I64d%I64d",&l[i],&r[i],&q[i]);
for(int bit=0;bit<=31;bit++)
{
if((q[i]>>bit)&1)
{
a[l[i]][bit]++;
a[r[i]+1][bit]--;
}
}
}
for(int bit=0;bit<=30;bit++)
{
for(int i=1;i<=n;i++)
a[i][bit]+=a[i-1][bit];
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<=32;j++)
{
if(a[i][j]>=1)
b[i]|=1ll<<j;
}
// printf("%d ",b[i]);
}
build(1,1,n);
bool flag=true;
for(int i=1;i<=m;i++)
{
ll res=query(1,l[i],r[i]);
if(res!=q[i])
flag=false;
}
if(flag)
{
puts("YES");
for(int i=1;i<=n;i++)
printf("%I64d ",b[i]);
}
else
puts("NO");
return 0;
}