2021牛客暑期多校训练营#8:D-OR

2021牛客暑期多校训练营#8:D-OR

原题链接:https://ac.nowcoder.com/acm/contest/11259/K

题目大意

给定两个长度为 n − 1 n-1 n1的非负整数序列 b = ( b 2 , b 3 , … , b n ) , c = ( c 2 , c 3 , … , c n ) b=(b_2,b_3,\ldots,b_n),c=(c_2,c_3,\ldots,c_n) b=(b2,b3,,bn),c=(c2,c3,,cn)。求满足以下条件的非负整数序列 a a a的数量:
− ∀ i ∈ [ 2 , n ] , b i = a i − 1 ∣ a i , c = a i − 1 + a i ; -\forall i\in[2,n],b_i=a_{i-1}|a_i,c=a_{i-1}+a_i; i[2,n],bi=ai1ai,c=ai1+ai;

解题思路

由于加法存在烦人的进位操作,所以首先考虑进位的情况:
1. 第 i 位 都 是 1 , 进 位 ; 2. 第 i 位 都 是 0 , 不 变 ; 3. 第 i 位 一 个 0 一 个 1 , 变 成 1 。 \begin{aligned} &1.第i位都是1,进位;\\ &2.第i位都是0,不变;\\ &3.第i位一个0一个1,变成1。 \end{aligned} 1.i12.i03.i011

而位或运算和位与运算的关系是
1. 第 i 位 都 是 1 , 变 成 1 ; 2. 第 i 位 都 是 0 , 是 0 ; 3. 第 i 位 一 个 0 一 个 1 , 变 成 1 。 \begin{aligned} &1.第i位都是1,变成1;\\ &2.第i位都是0,是0;\\ &3.第i位一个0一个1,变成1。 \end{aligned} 1.i112.i003.i011
我们可以发现
c i = a i − 1 ∣ a i + a i − 1 & a i c_i=a_{i-1}|a_i+a_{i-1}\&a_i ci=ai1ai+ai1&ai。所以我们只要枚举 a i − 1 a_{i-1} ai1 a i a_i ai的位即可。

代码实现

#include<bits/stdc++.h>
using namespace std;
int b[199991],c[199991],a,n,ans=1;
int main()
{
	cin>>n;
	for(int i=2;i<=n;i++)
	cin>>b[i];
	for(int i=2;i<=n;i++)
	cin>>c[i],c[i]-=b[i];
	for(int i=0;i<31;i++)
	{
		int l=1,r=1;
		for(int j=2;j<=n;j++)
		{
			int x=b[j]>>i&1,y=c[j]>>i&1;
			int d=0,e=0;
			if(x&&y)e=r;
			if(x&&!y)d=r,e=l;
			if(!x&&!y)d=l;
			l=d,r=e;
		}
		ans*=l+r;
	}
	cout<<ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值