题解 CF643F 【Bears and Juice】
CF643F Bears and Juice
题意
- 有
n 只熊和p 张床,还有若干个无限大的酒桶(至少一个),其中恰好只有一个酒桶里装着酒,其它酒桶里都装着果汁。 - 熊一开始不知道哪桶里面是酒,于是进行了一次挑战,目标是找到哪桶里面是酒。
- 每天,每只还醒着的熊会选择一个酒桶的子集(可以为空集),并且喝下选择的酒桶中的一小杯饮料。
- 如果一只熊喝到了酒,它会上床睡觉一直到挑战结束。但一张床只能容纳一只熊,如果有熊没有床睡觉,则挑战失败。
- 如果
i 天后至少还剩一只熊没睡觉,且能根据前面的线索推理出哪桶里面是酒,则挑战成功。 - 请你求出对于
i \in [1,q] ,在可以确保挑战成功的情况下,最多有多少个酒桶。 - 设对于
i 的答案为R_i ,你需要求出\operatorname{xor}_{i=1}^q ((i \times R_i) \bmod 2^{32}) 。 -
题解
这道题需要从「信息」的角度考虑。什么叫从「信息」的角度呢?
举个例子,我们都知道
显然一共有
每次比较可以得到的全部「信息」为两个元素的相对顺序,根据这个「信息」,有一半的方案会被区分掉,还剩下一半的方案。
那么
回到本题,我们能够得到的全部「信息」为:
- 一只熊最终有没有睡觉。
- 如果它睡觉了,是在第几天睡的。
根据这些「信息」,当天数为
解释一下这个公式:
- 枚举睡觉的熊的个数
j ,由于一共只有p 张床,而不能所有熊都睡觉,因此睡觉的熊的个数最多为\min(p,n-1) 。 -
- 每只睡觉的熊可以在
i 天中选择一天睡觉,j 只熊的方案数为i^j 。
那这个上界是否一定能达到呢?
我们将所有的方案排成一排,第
如果在第
这样,我们就构造出来了一种达到上界的情况。
于是,我们现在要计算的式子为:
直接暴力枚举
但问题在于这个组合数
注意到
对于
这样到最后,分母一定会被约为
总时间复杂度
代码
const ui N = 137;
ui n, p, q, ans[N], Ans;
inline ui calc(ui j) {
vector<ui> a, b;
for (ui i = 1; i <= j; i++)
a.pb(n + 1 - i), b.pb(i);
for (ui &x : a)
for (ui & y : b) {
ui d = __gcd(x, y);
x /= d, y /= d;
}
ui ans = 1;
for (ui x : a) ans *= x;
return ans;
}
int main() {
rd(n), rd(p), rd(q), p = min(p, n - 1);
for (ui j = 0; j <= p; j++) ans[j] = calc(j);
for (ui i = 1; i <= q; i++) {
ui now = 0;
for (ui j = 0, k = 1; j <= p; j++, k *= i)
now += ans[j] * k;
Ans ^= now * i;
}
print(Ans);
return 0;
}