CF643F Bears and Juice 题解
被黑题吓死了。
如何计算答案
首先需要注意酒桶和熊都是区分的,不要读错题目意思了。
不妨先来考虑一些简单的情况。
考虑
- 对于只有一个床位的情况:挨个试过去即可。
天最多可以区分 桶。 - 对于只有一天,但是允许醉倒很多熊:直接二进制分组。
然而其余的状态其实并不是很好解决。不妨先考虑有
你发现,由于醉倒的熊需要占据相同个数的床位,因此我们只需要记录其中一个即可。
我们现在的问题变成了,在还能醉倒
我们继续观察我们每天可以做什么操作。实际上是下面这个东西:
- 对于每个还醒着的熊
,分配一个桶的集合 。 - 这一天结束的时候,
- 如果第
头熊醒着,说明 里没有酒,酒在 的补集里。此时将 补和候选集合取交集即可。 - 如果第
头熊醉倒了,说明 里有酒。此时将候选集合和 取交集。
- 如果第
最后会剩下来一个候选集合
因此这实际上构成了一个子问题,可以递归的求解。
为了能区分出这么多饮料,我们需要保证以下几点:
- 对于每一种可能出现的结果(每一头熊是否醉倒)及其结果
,满足: - 醉倒的熊的个数
小于等于 。 - 可以在醉倒
头熊,剩下 天的情况下区分出 桶酒。
- 醉倒的熊的个数
形式化的,令
我们每次的操作实际上是:
- 对于第
头熊,将饮料集合 划分为不交的集合 和 。熊 喝 里的酒。 - 将每天晚上的结果记成一个长度为
的 字符串 , 当且仅当熊 喝完酒醉倒了。 - 构造候选集合
。 - 醉倒的熊的个数
。
对于每个可能出现的
我们发现一个问题:我们的
我们注意到一个性质:如果你能区分
结论是显然的,对于方案的构造可以考虑补上若干桶一定不是酒的饮料转化成大小为
因此,对于相同的
也就是说,让
根据二进制分组的想法,对于所有可能出现的结果
我们反过来考虑,对于每个结果
反过来构造方案也是容易的,如果
然后我们发现这个转移之和
然后我们发现这个转移之和
也就是:
但是还没结束!这个暴力复杂度是
更快的计算方法
考虑打表找规律。此时打出来的表会十分有规律。固定床位
此时你可以直接猜
不过没关系!我们求出的是一段连续的值,因此可以差分之后再前缀和回去。
由于
具体的,求出前
我们接下来考虑归纳的证明这个结论。
引理
: 是 次多项式。
这点其实非常容易理解。这就是说,此时不能接受任何熊醉倒,因而只能区分
引理
:若对于 满足 是不超过 次的多项式,那么 是不超过 次的多项式。
我们把我们的 dp 转移用新的符号重新写出来。
提出来一个
首先右侧的
这实际上是说: