[2018.10.15 T1] 或

本文探讨了如何使用位运算解决特定序列构建问题,通过维护30个序列进行区间赋值操作,最终构造出满足条件的序列,并用线段树进行验证。适用于喜欢算法挑战的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

暂无连接

【题目描述】

小Q非常喜欢序列和位运算。

有一天,小Q想到了一个模型:一个长度为nnn的非负整数序列xxx,满足mmm个条件:第iii个条件为x[li] or x[li+1] or ⋯ or x[ri]=pix[l_i]\ or\ x[l_{i+1}]\ or\ \cdots\ or\ x[r_i]=p_ix[li] or x[li+1] or  or x[ri]=pi。他想知道是否存在一个序列满足条件,如果存在,他还要构造出一个这样的序列。

【输入】

第一行两个整数n,mn,mn,m。接下来mmm行每行三个整数li,ri,pil_i,r_i,p_ili,ri,pi

【输出】

如果存在这样的序列xxx,第一行输出Yes,第二行输出nnn个不超过230−12^{30}−12301的非负整数表示x[1]∼ x[n]x[1]\sim ~x[n]x[1] x[n],否则输出一行NoNoNo

【输入样例】

2 1
1 2 1

【输出样例】

Yes
1 1

【提示】
【数据规模及约定】

对于30%30\%30%的数据,n,m≤1000n,m≤1000n,m1000
对于另外30%30\%30%的数据,pi≤1p_i≤1pi1
对于100%100\%100%的数据,n,m≤100,000,1≤li≤ri≤n,0≤pi&lt;230n,m≤100,000,1≤l_i≤r_i≤n,0≤p_i&lt;2^{30}n,m100,0001lirin0pi<230

题解

如果一段区间ororor起来某几位等于000,那么该区间的这几位必须全部为000,所以我们开303030个序列维护每一位,通过查分做区间赋000操作。

最后按照我们构造出的每一位得出答案,用线段树checkcheckcheck一下即可。

代码
#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();}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShadyPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值