题目大意
你原本有个长度为的序列
,现在我只告诉你两个长度为
的序列
,问合理的
序列有多少种?
我们定义。
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; }