题目大意
你原本有个长度为的序列
,现在我只告诉你两个长度为
的序列
,问合理的
序列有多少种?
我们定义。
Solution
由于给出的数组都是位运算得来的,我们就可以按位拆分,枚举
的每一位,再去枚举不同的数。
我们首先看最低位,注意下面的代表着当前枚举的这一位二进制是
还是
,
同理,映射到题目就是
:
如果在最低位的情况下,这样的
一共有
个说明我们这一位存在两种构建方法,即
或者
这样交替进行。
我们把不足位我们可以分成下面的情况。
如果在最低位的某一个,说明它一定产生了进位,那么我们就把这次产生的进位消除,当我们每次都消除进位的时候就可以一直当作最低位处理了,例如
,在我们消除最低位的
带来的影响后
它的第二位第三位都可以看作新的最低位处理了。
如果在最低位的某一个这一定是非法的,因为最低位不可能有来自进位的
。
如果在最低位的某一个,我们就看它进位是不是来自
如果是刚刚前两个
的话说明当前的这个
不可能是
,一定会存在一个
让它进位。那么其余合法的时候例如
后面跟一个
这是合法的,但是出现了这样的进位说明当前这一位我们也只有一种构造
序列的方法。
const int N = 1e5 + 7;
ll n, m;
int b[N], c[N];
int solve() {
n = read();
for (int i = 1; i < n; ++i) b[i] = read();
for (int i = 1; i < n; ++i) c[i] = read();
for (int i = 1; i < n; ++i) {
if (b[i] > c[i]) {
return print(0), 1;
}
}
ll res = 1;
for (int i = 0; i < 34; ++i) {
int cnt = 0, pos = -100;
for (int j = 1; j < n; ++j) {
int bit1 = b[j] >> i & 1, bit2 = c[j] >> i & 1;
if (bit1 == 1 && bit2 == 1) ++cnt;
else if (bit1 == 1 && bit2 == 0) {
c[j] -= (1ll << i);
pos = j;
}
else if (bit1 == 0 && bit2 == 1) {
return print(0), 0;
}
else if (bit1 == 0 && bit2 == 0) {
if (pos == j - 1) {
return print(0), 0;
}
}
}
if (cnt == n - 1) res *= 2;
}
print(res);
return 1;
} 
京公网安备 11010502036488号