偷吃蛋糕
idea, solution, std, data from GeZhiyuan
足够暴力的搜索
我们考虑一个足够暴力的搜素:当每次转交蛋糕时,暴力枚举被老鼠偷了哪一层,并递归为多个子问题。
该算法看起来是
但由于出题人不想让大家轻松拿到
一个明显的剪枝
我们考虑,对于两个不同的下标
如何分析复杂度呢?我们考虑根号分治。
如果大小大于
对于大小不大于
这样最终可达的状态数为
加一点神奇的小优化
我们考虑对于一层蛋糕,如果吃这层蛋糕时,主办方已经给你了所有的蛋糕,那么其对答案的贡献一定为其大小,即对于这些吃时,主办方已经给你所有蛋糕的蛋糕层。我们只在意这些层的大小乘以其能拿到手中的概率之和。即如下搜索:
- 如果已经获得过的蛋糕的大小之和,超出了
。则快速贡献,并计算答案。 - 否则考虑吃掉一层蛋糕,并枚举转交蛋糕时,老鼠偷的蛋糕的大小,并带权向多侧递归。
并还可以进行如下优化:
- 考虑
时, 才有可能在搜索时被吃,即只有 种可能进入搜索的大小。 - 于是考虑如果下一次转交,只有一种大小,则可以快速跳过这些转交,直到下一个转交至少两种大小的区间。
- 即假设当前手上的蛋糕大小为
,有 个,接下来的 层蛋糕大小相同,且第 层蛋糕大小与他们不同。 - 那么此时如果有
,那么我们可以直接快速跳 次,下一次吃蛋糕时蛋糕大小种类数至少为 。否则我们考虑吃掉大小为 的所有蛋糕,此时在后续搜索中,只会吃到大小比 小的蛋糕。
假设搜索到达最终状态数个数为
关于此题可行性
pp_orange 指出,我们的搜索可以刻画为一棵多叉树,状态数即多叉树的大小。本题中我们只在意叶子的个数,如果叶子数是
我们即要找出多叉树叶子个数最大的情况。考虑一个状态有
于是我们即只要找到一种最差的分裂情况,最大化代价为分叉数的乘积即可。考虑分叉数依次为
不难发现第
由于我们经过了缩放,此时不难发现,值域连续且包含
由于值域连续,此时
如下是检验用的代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 3000 + 5, M = 100 + 5, Inf = 1e18;
inline void checkmax(ll &x, ll y){
if(y > x) x = y;
}
ll n = 0, m = 80;
ll dp[N][M] = {}, ans = 0;
int main(){
scanf("%lld", &n);
for(ll x = 1 ; x <= m ; x ++) dp[x][x] = x;
for(ll x = m ; x >= 1 ; x --) for(ll y = x + 1 ; y <= n ; y ++){
ll d = x * x + (x + y) * (y - x - 1) / 2;
for(ll c = 0 ; c + d <= n ; c ++) checkmax(dp[c + d][x], dp[c][y] * (y - x + 1));
}
for(ll c = 0 ; c <= n ; c ++) ans = max(ans, dp[c][1]);
printf("%lld", ans);
return 0;
}
复杂度分析
作为选手可以直接写代码然后通过此题,但是对于出题人显然是另一件事。需要证明更为严谨的复杂度。
通过手玩可能大概猜测在
根据公理,询问 zhoukangyang 一个命题是真的还是假的,构成了一个严格的证明。
那我们就只需要询问到底是
现在我们已经知道了正确的时间复杂度!让我们尝试给出详细的过程。
假设搜索过程递归了
考虑第
那么不难发现有
由于我们有
因此有
即我们现在需要求有多少个递增正整数序列
接下来由 zhoukangyang 全权负责:
- 先只考虑
的元素,这个意思大概是你有 个 量级的元素,每个元素可以选任意多个,最终不超过 的方案数,这个是 。 先考虑
的情况,设 。使用斯特林公式, 量级是 ,即 。我们已经有
。主要是 。这个就是 。 通过令 ,转为 ,这个是 量级的。接下来考虑
的情况,设 ,组合数为 ,量级是 。同样有
,我们只需要分析 ,即 。 通过令 ,转为 ,也是 量级的。
综上所述,复杂度
百尺竿头更进一步
from zhoukangyang
这题实际上存在理论复杂度更优的做法。
考虑将获得蛋糕的过程分成若干轮。第一轮获得
考虑提前枚举每一轮被转交了哪些蛋糕(不枚举哪些被老鼠拿走了)。对于每个蛋糕 fa[x]=y
。容易发现这形成了一棵树。
可以在树上 DFS 同时 DP:维护当时 DFS 栈中的元素以及还有几个孩子没被递归。此时大概要记深度个
因此考虑深度需要到多少。容易发现,在
因此深度是
咕咕咕
在 此题可行性 部分中说明了此题搜索上界,但我们没有一组足够强的数据能贴合上界的量级,搜索已经证明的下界和上界差距仍然很大。如果你能将上界分析到更低或给出更强的数据,欢迎在题解下方讨论!
环环相扣
idea from Demeanor; solution, std, data from zhoukangyang, Melania
准备工作
我们的题目要求对于每个查询区间
假设我们选择的值
,其能量值等于 。 ,其能量值等于 。
结论 1:只要
这是因为
算法 1
结论 2:查询区间内的第一大值和第二大值必须分别作为
这是解决这个问题的突破口。
基于这一结论,可以实现一个时间复杂度为
- 对于每个询问
,扫描整个区间确定第一大值和第二大值,分别记为 和 。 - 枚举
内所有可能的 ,注意排除 和 本身。 - 对于每个
,分别计算两种排列方式 和 的能量值。 - 直接输出这
个能量值中的最大值。
结论 2 的证明如下:
- 不妨假设区间为
,其中 。 - 直接选择
并使用排列方式 2,可以得到答案的一个下界 。 - 我们利用结论 1:
- 对于排列方式 1:
。对于 或 ,这一值不会超过下界。 - 对于排列方式 2:
。对于 ,这一值不会超过下界。此外,由于 只在和式里面出现一次,显然当 时能量值取到最大。
- 对于排列方式 1:
算法 1 的时间复杂度为
算法 2
定义
我们可以把两种排列方式的能量值重写为:
- 排列方式 1:
。 - 排列方式 2:
。
我们将
我们考虑预处理所有的
- 对于每个
,从右向左扫描 。 - 维护当前排除掉的最大元素
。 - 如果
,则用 更新 ,然后设置 。 - 如果
,则用 更新 。
预处理所有的
由于拆分操作排除了左右两侧的最大元素,我们需要手动加回两侧最大元素当中较小的那一个。
算法 2 的时间复杂度为
算法 3
我们可以通过限制向左扫描的长度,减小预处理
结论 3:在扫描过程中,如果遇到两个元素
- 由于有两个这样的元素,排除一个最大元素后仍然有一个元素
。 - 如果
,则 本来就不能成为 内的第一大值或第二大值,因此 的值不会被使用。 - 如果
,则 ,已经达到了上界,继续向左扫描也没有用。
我们使用 zkw 线段树来定位到
利用结论 3 可以证明总扫描长度为
算法 4
我们进一步优化算法 3,将总扫描长度减小到
结论 4:针对
这是因为
结论 3、结论 4 之间十分的相契。最后算法的实现步骤如下:
- 使用
vector<pair<int, long long>>
存储满足 的位置 ,并记录对应的 。 - 使用一个栈存储尚未被移除的元素。
- 针对
向左扫描的过程中:- 从栈顶到栈底枚举所有元素
。 - 如果
,则计数器cnt++
。 - 如果
,则给 新增一个删除标记。 - 如果
cnt
达到 ,立刻停止扫描。 - 移除累积了两个删除标记的元素。
- 将具有一个或零个删除标记的元素按照原顺序压回栈中。
- 从栈顶到栈底枚举所有元素
- 最后将
以初始零个删除标记压入栈中。
这确保了总扫描长度为
算法 4 的时间复杂度为
水仙平原
idea, solution, std, data from Melania
在这篇文章中,我们使用
这个问题只是 CF1924F 的加强版,在这篇文章中对应于 TTT
FFF
排除一个奇数位置
考虑在什么条件下,一个奇数位置
假设选手已经进行了
对于每个奇数位置 T
和 F
组成:
- 如果
是<
且 ,或者如果 是>
且 ,则 为T
。 - 如果
是<
且 ,或者如果 是>
且 ,则 为F
。
因此,T
还是假话 F
,假设小老鼠实际上位于位置
如果
构建 Aho-Corasick 自动机
为了刻画这一条件,我们构建
一个由 T
和 F
组成的字符串
一部分字典树结点本身就是不合法的。除了直接对应于
结论 1:
结论 1 的证明:
- 从根结点出发,直接沿着树边行走可以到达所有合法结点。
- 从任何一个合法结点出发,通过长度不超过
的一连串T
边,都可以返回到根结点。- 由于
中的所有字符串都以F
结尾,追加一系列T
不会使一个原本合法的字符串变的不合法。 - 由于
中的所有字符串都以F
开头,追加最多 个T
可以确保自动机匹配的最长后缀回退到空后缀。
- 由于
因此,如果只保留合法结点以及它们在
交互库的实现
我们站在交互库的角度思考问题。作为交互库,我们需要维护哪些
对于每个奇数
如果决定对查询
回答<
:给所有 的 追加一个F
,给所有 的 追加一个T
。如果决定对查询
回答>
:给所有 的 追加一个T
,给所有 的 追加一个F
。
在
站在交互库的角度思考,交互库可以自由选择回答 <
还是 >
。
一种直接的实现是:选择排除
然而,这种直接的实现并不理想,因为某些合法结点比其他结点更接近被排除。例如,距离被排除只差一个 F
的结点被认为是更受威胁的结点。为了解决这个问题,我们引入了结点势能的概念。
势能的定义
为每个字典树结点
结论 2: 设 T
和 F
组成的字符串 T
和 F
字符串。
对于所有合法结点
使用线性代数来建模自动机。设 F
或 T
从
由于
- 存在一个实数
( 的谱半径),其值超过任何其他特征值的绝对值。 - 存在对应于
的正的左特征向量和右特征向量。
函数
势能的使用
定义结点势能的动机如下:如果所有存活结点的当前总势能为 <
后,总势能变为 >
后,总势能变为
交互库的策略: 交互库计算每种可能回答的 <
或 >
)。这确保了:
选手的策略: 选手旨在最小化
为了实现这一策略,维护具有相同
- 如果回答是
<
:- 对于所有
,将 更新为 。 - 对于所有
,将 更新为 。
- 对于所有
- 如果回答是
>
:- 对于所有
,将 更新为 。 - 对于所有
,将 更新为 。
- 对于所有
- 如果
位于一个区间 内:- 将该区间拆分为
和 。 - 按上述方式进行更新。
- 将该区间拆分为
每个查询都会拆分一个连续的区间,导致时间复杂度为
为了进一步优化,排除所有被淘汰的区间并仅保留活动区间,将时间复杂度降低到
或者,实施一个动态区间树,每个结点维护该区间内所有
势能的近似计算
计算并使用精确的实数
由于数轴的长度为 uint128
,且势能为 uint64
,因此需要实现高精度的无符号整数(例如 uint192
)。这些必须支持加法、减法、比较,以及通过 uint128
和 uint64
的乘积进行初始化。
收敛性考虑: 定义相对误差
未解决的问题 1: 我们无法提供
下界和上界 和 的计算
我们在问题陈述中提到存在两个合理的过程 compute_lower_bound()
和 compute_upper_bound()
,用于根据输入数据自动计算
计算下界
:- 从总势能
开始。 - 在每次迭代中,更新
。 是第一次迭代使得 的迭代次数。
这是因为在任何剩余存活位置
的状态下,总势能必须 。- 从总势能
计算上界
:- 从总势能
开始。 - 在每次迭代中,更新
。 是第一次迭代使得 的迭代次数,其中 是所有合法结点中的最小势能。
这是因为在任何总势能
的状态下,剩余存活位置必须 。- 从总势能
未解决的问题 2: 我们无法提供
Information Chart
Information Chart:
bluff1.in: L = 60, R = 60, h_sum = 1, h_max = 1, ratio = 1
bluff2.in: L = 174, R = 177, h_sum = 2, h_max = 2, ratio = 1.01724
bluff3.in: L = 174, R = 177, h_sum = 2, h_max = 2, ratio = 1.01724
bluff4.in: L = 174, R = 177, h_sum = 2, h_max = 2, ratio = 1.01724
bluff5.in: L = 440, R = 449, h_sum = 3, h_max = 3, ratio = 1.02045
bluff6.in: L = 440, R = 449, h_sum = 3, h_max = 3, ratio = 1.02045
bluff7.in: L = 440, R = 449, h_sum = 3, h_max = 3, ratio = 1.02045
bluff8.in: L = 282, R = 287, h_sum = 3, h_max = 3, ratio = 1.01773
bluff9.in: L = 282, R = 287, h_sum = 3, h_max = 3, ratio = 1.01773
bluff10.in: L = 282, R = 287, h_sum = 3, h_max = 3, ratio = 1.01773
bluff11.in: L = 8008, R = 8185, h_sum = 7, h_max = 7, ratio = 1.0221
bluff12.in: L = 5288, R = 5404, h_sum = 7, h_max = 7, ratio = 1.02194
bluff13.in: L = 4507, R = 4604, h_sum = 7, h_max = 7, ratio = 1.02152
bluff14.in: L = 4379, R = 4474, h_sum = 7, h_max = 7, ratio = 1.02169
bluff15.in: L = 4245, R = 4337, h_sum = 7, h_max = 7, ratio = 1.02167
bluff16.in: L = 4113, R = 4203, h_sum = 7, h_max = 7, ratio = 1.02188
bluff17.in: L = 4113, R = 4203, h_sum = 7, h_max = 7, ratio = 1.02188
bluff18.in: L = 3911, R = 3996, h_sum = 6, h_max = 6, ratio = 1.02173
bluff19.in: L = 2218, R = 2265, h_sum = 6, h_max = 6, ratio = 1.02119
bluff20.in: L = 2085, R = 2130, h_sum = 6, h_max = 6, ratio = 1.02158
bluff21.in: L = 9725, R = 9952, h_sum = 225452, h_max = 31, ratio = 1.02334
bluff22.in: L = 9404, R = 9618, h_sum = 226966, h_max = 32, ratio = 1.02276
bluff23.in: L = 8986, R = 9190, h_sum = 226346, h_max = 32, ratio = 1.0227
bluff24.in: L = 8796, R = 8988, h_sum = 222071, h_max = 31, ratio = 1.02183
bluff25.in: L = 8606, R = 8799, h_sum = 264821, h_max = 41, ratio = 1.02243
bluff26.in: L = 8571, R = 8757, h_sum = 246295, h_max = 37, ratio = 1.0217
bluff27.in: L = 8177, R = 8362, h_sum = 240395, h_max = 36, ratio = 1.02262
bluff28.in: L = 7525, R = 7695, h_sum = 224467, h_max = 31, ratio = 1.02259
bluff29.in: L = 7011, R = 7170, h_sum = 221676, h_max = 31, ratio = 1.02268
bluff30.in: L = 5961, R = 6125, h_sum = 238018, h_max = 35, ratio = 1.02751
bluff31.in: L = 146449, R = 149955, h_sum = 305501, h_max = 41, ratio = 1.02394
bluff32.in: L = 146446, R = 149939, h_sum = 359112, h_max = 49, ratio = 1.02385
bluff33.in: L = 146402, R = 149885, h_sum = 304109, h_max = 40, ratio = 1.02379
bluff34.in: L = 145973, R = 149435, h_sum = 365159, h_max = 48, ratio = 1.02372
bluff35.in: L = 145067, R = 148518, h_sum = 418110, h_max = 55, ratio = 1.02379
bluff36.in: L = 141704, R = 145065, h_sum = 315053, h_max = 42, ratio = 1.02372
bluff37.in: L = 137359, R = 140572, h_sum = 269882, h_max = 34, ratio = 1.02339
bluff38.in: L = 131976, R = 135018, h_sum = 358775, h_max = 49, ratio = 1.02305
bluff39.in: L = 127469, R = 130391, h_sum = 411627, h_max = 54, ratio = 1.02292
bluff40.in: L = 117471, R = 120090, h_sum = 414802, h_max = 55, ratio = 1.02229
ex_bluff1.in: L = 60, R = 60, h_sum = 1, h_max = 1, ratio = 1
ex_bluff2.in: L = 174, R = 177, h_sum = 2, h_max = 2, ratio = 1.01724
ex_bluff3.in: L = 440, R = 449, h_sum = 3, h_max = 3, ratio = 1.02045
ex_bluff4.in: L = 282, R = 287, h_sum = 3, h_max = 3, ratio = 1.01773
ex_bluff5.in: L = 4507, R = 4604, h_sum = 7, h_max = 7, ratio = 1.02152
ex_bluff6.in: L = 9221, R = 9430, h_sum = 224402, h_max = 30, ratio = 1.02267
ex_bluff7.in: L = 145099, R = 148531, h_sum = 416453, h_max = 54, ratio = 1.02365