补题链接:https://ac.nowcoder.com/acm/contest/11259/D
作此题需要的前导知识: =
+
而题中给出: =
,
=
所以设 =
=
此时有 =
,
=
所以此时对于的每一位我们可以分开考虑(它只与当前位有关),
所以我们可以枚举的每一位(不是1就是0),
设初始,
如果(的当前位取1或着0)推出
,
,…,
, (0或着1)只有一个满足
,
,…,
,和
,
,…,
说明当前位只有一种选择,
,
如果(0或者1)都满足则,
如果(0或者1)都不满足,则
(相当于判断二进制数的每一位有多少种选择,然后推出 进制的数有多少个)
AC code
using namespace std;
const int N = 1e5 + 10;
typedef long long ll;
int a[N], b[N], c[N], d[N];
int n;
bool check(int idx, int x){
int v[n + 1]; // 记录ai的当前idx位的值
v[1] = x;
for(int i = 2; i <= n; i++){
// 获取b数组的第i个数的idx位和d数组的第i个数的idx位
int nd = (d[i] >> idx) & 1, nb = (b[i] >> idx) & 1;
// ai-1 & ai == 1
if(nd){
// ai-1 | ai == 1
if(nb){
if(v[i - 1]){
// 两个数 & 为1,两个数 | 为1,两个数一定都为1
v[i] = 1;
}else{
// 如果v[i-1]为0,则不满足
return 0;
}
}else{ // ai-1 | ai == 0
// &为1, | 为0,矛盾
return 0;
}
}else{ // ai-1 & ai == 0
// ai-1 | ai == 1
if(nb){ // 与为0,或为1,则一个为0,一个为1
if(v[i - 1]) v[i] = 0;
else v[i] = 1;
}else{// ai-1 | ai == 0
// 两个只能都为0
if(v[i - 1]) return 0;
v[i] = 0;
}
}
}
return 1;
}
int main(){
scanf("%d", &n);
for(int i = 2; i <= n; i++){
scanf("%d", &b[i]);
}
for(int i = 2; i <= n; i++){
scanf("%d", &c[i]);
}
for(int i = 2; i <= n; i++){
d[i] = c[i] - b[i];
}
ll ans = 1;
// 枚举a1的每一位,判断对于每个 d 的相应位,是否满足
for(int i = 0; i < 30; i++){
ans *= (check(i, 0) + check(i, 1));
}
printf("%lld\n", ans);
return 0;
}