D OR
此题关键: a + b = ( a ∣ b ) + ( a & b ) a+b=(a|b)+(a\&b) a+b=(a∣b)+(a&b)
这个公式可以这么理解,将 a , b a,b a,b 用二进制表示,对于上面的公式而言,单独某一位的加是等效的,例如:若 a , b a,b a,b 的某一位都为 1 1 1 ,或运算以后那一位仍未 1 1 1 ,与运算以后也为 1 1 1 ,仍然是两个 1 1 1 相加,其他情况同理,所以这个公式是正确的。
那么利用这个公式,我们就可以得到相邻两项之间的与运算结果和或运算结果,那么限制条件就变成了对于二进制的每一位而言都是独立的。且我们知道,只要 a 1 a_1 a1 确定,整个序列就确定,我们只需要确实是否合法,那么现在限制条件已经变成了某一位独立的了。那么我们只要去确定 a 1 a_1 a1 的二进制的每一位的情况,最后将情况数连乘即是答案。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int n;
ll b[N], c[N], ans = 1;
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
scanf("%d", &n);
for (int i = 1; i < n; ++i) {
scanf("%lld", &b[i]);
}
for (int i = 1; i < n; ++i) {
scanf("%lld", &c[i]);
c[i] -= b[i];
}
for (int i = 30; i >= 0; --i) {
int cnt = 0;
for (int bit = 0; bit < 2; ++bit) {
int pre = bit;
bool ok = true;
for (int j = 1; j < n; ++j) {
int huo = (b[j] >> i) & 1, yu = (c[j] >> i) & 1;
if ((pre & 0) == yu && (pre | 0) == huo) pre = 0;
else if ((pre & 1) == yu && (pre | 1) == huo) pre = 1;
else {
ok = false;
break;
}
}
if (ok) cnt++;
}
ans *= cnt;
}
printf("%lld", ans);
}