题目描述
输入描述
输出描述
输入样例
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;
}