OR(2021牛客多校第八场D)

题目描述

在这里插入图片描述

输入描述

在这里插入图片描述

输出描述

在这里插入图片描述

输入样例

4
7 5 5
7 9 5

输出样例

2

题目大意:给定两个数组 b、c,现需要构造一个数组 a 使得
在这里插入图片描述
求数组有多少种满足条件的数组 a 。

写题的时候一直想的是找到每组 b 与 c 不同的数对及该组的唯一答案,并判断两两间是否能够对接。但其实这种唯一性完全可以仅在 a 数组上体现,因 a 数组的每一项都受到前一项的制约,因此只考虑 a1 的可能性即可将整个 a 数组都进行一个梗概。

由数学结论可知,a + b = a or b + a and b,因此不妨先将 c 数组转化为两数之与,这样可以免去考虑加法进位问题,仅需按位考虑。

在这里插入图片描述
构造 c 数组为 c - b,不难发现,当 c = 0 且 b = 1 时,数位对应有 0、1 两种选择,而当 b = c = 0 时,数位对应只有 0 一种选择;b = c = 1 时,数位对应只有 1 一种选择。因此可对 b、c 数组中每项的对应位进行判断,得出该位 a1 的可能性。需要注意的是,数组 a 中后一项会受到前一项影响,因此当 a1 = a2 = 0 而 b3 = c3 = 1 时,理论上需要 a2 = a3 = 1,因此该样例无解。

参考代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N=1e5+10;
const ll mod=4933;

int b[N],c[N];

int main()
{
	int n,flag=0,pos;
	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];
	}
	int ans=1;
	for(int i=0;i<31;i++){
		int flag=2,fron=-1;
		for(int j=2;j<=n;j++){
			int bn=b[j]>>i&1;
			int cn=c[j]>>i&1;
			if(bn==cn&&flag==2){
                flag=1;
                if(bn==0)fron=0;
                else fron=1;
            }
            else if(bn&&cn==0&&flag==1){
                if(fron==0)fron=1;
                else fron=0;
            }
            else if(bn==cn&&flag==1){
                if((bn==0&&fron==1)||(bn==1&&fron==0)){
                    cout<<"0"<<endl;
                    return 0;
                }
                if(bn==0)fron=0;
                else fron=1;
            }
			else if(bn==0&&cn){
				cout<<"0"<<endl;
                return 0;
			}
		}
		ans=ans*flag;
	}
	cout<<ans<<endl;
	
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值