版权声明:大佬您能赏脸,蒟蒻倍感荣幸,还请联系我让我好好膜拜。 https://blog.csdn.net/ShadyPi/article/details/83068182
暂无连接
或
【题目描述】
小Q非常喜欢序列和位运算。
有一天,小Q想到了一个模型:一个长度为 的非负整数序列 ,满足 个条件:第 个条件为 。他想知道是否存在一个序列满足条件,如果存在,他还要构造出一个这样的序列。
【输入】
第一行两个整数 。接下来 行每行三个整数 。
【输出】
如果存在这样的序列 ,第一行输出Yes,第二行输出 个不超过 的非负整数表示 ,否则输出一行 。
【输入样例】
2 1
1 2 1
【输出样例】
Yes
1 1
【提示】
【数据规模及约定】
对于
的数据,
。
对于另外
的数据,
。
对于
的数据,
。
题解
如果一段区间 起来某几位等于 ,那么该区间的这几位必须全部为 ,所以我们开 个序列维护每一位,通过查分做区间赋 操作。
最后按照我们构造出的每一位得出答案,用线段树 一下即可。
代码
#include<bits/stdc++.h>
#define ls v<<1
#define rs v<<1|1
using namespace std;
const int M=1e5+5,bit=30;
int que[bit+2][M],ans[M],sum[M<<2],l[M],r[M],p[M],n,m;
void in(){scanf("%d%d",&n,&m);}
void up(int v){sum[v]=sum[ls]|sum[rs];}
void build(int v,int l,int r)
{
if(l==r){sum[v]=ans[l];return;}
int mid=l+r>>1;
build(ls,l,mid);build(rs,mid+1,r);
up(v);
}
int ask(int v,int le,int ri,int lb,int rb)
{
if(lb<=le&&ri<=rb){return sum[v];}
int mid=le+ri>>1,ans=0;
if(lb<=mid)ans=ask(ls,le,mid,lb,rb);
if(mid<rb)ans|=ask(rs,mid+1,ri,lb,rb);
return ans;
}
void ac()
{
for(int i=0;i<bit;++i)que[i][0]=1;
for(int i=1,j;i<=m;++i)
{
scanf("%d%d%d",&l[i],&r[i],&p[i]);
for(j=0;j<bit;++j)
if(!(p[i]>>j&1))--que[j][l[i]],++que[j][r[i]+1];
}
for(int i=0,j;i<bit;++i)for(j=1;j<=n;++j)que[i][j]+=que[i][j-1];
for(int i=0,j;i<bit;++i)for(j=1;j<=n;++j)if(que[i][j]==1)ans[j]|=1<<i;
build(1,1,n);
for(int i=1;i<=m;++i)if(ask(1,1,n,l[i],r[i])!=p[i])puts("No"),exit(0);
puts("Yes");for(int i=1;i<=n;++i)printf("%d ",ans[i]);
}
int main(){in(),ac();}