CF750F New Year and Finding Roots
考虑第一步只能随机找点,找完点之后除非找到叶子或者根,不然完全等于啥都不知道。
于是找叶子节点,从这个点的两个邻边往下一直走一定能走到叶子,那么此时这条链的中点的父亲就被确定了。
多这么整几次,一直往上跳就肯定能找到根,但操作次数至多为 \(\sum\limits_{i}^{h-1}1=21\) 炸掉了。
事实上当深度 \(\le 4\) 的时候可以直接 BFS 至多 \(6\) 个点,这比 \(5+6=11\) 省多了,恰好 \(16\) 次可过。
评价:4/10,tag:丑陋、暴力、低智、难写。
CF1147E Rainbow Coins
很早之前没事做的,很普通的一道题。
一对点形如一条边,考虑连成链状分为两次进行询问。
此时已经可以知道任意相邻两点是否相同了,此时考虑间隔一个点,从 \(i\) 连到 \(i+2\),则可以获得一条额外的信息。
直接间隔,中间若有相同则等于没有信息,先缩点之后再问即可,要么和前两段某段颜色相同,要么都不同也可以确定。
总共只需要 \(2+2=4\) 次询问。
评价:6/10,tag:常规。
CF1007C Guess two numbers
长得很诡异的题。
考虑把询问搞成二维平面点,候选区间始终为左下角 L 形,该做法可做到 \(200\) 次询问,但难写且不优美还很低智。
这个问题的样子很二分,我们考虑如何进行二分,直接考虑二分会被各种卡住,怎么讨论都会死在某些情况上。
一个很巧妙的想法是把二分改为倍增,求出所求值的最大下界,设置步长在询问到小于时倍增,大于时除二即可。
https://www.luogu.com.cn/article/gfh5tuu3
评分:8/10,tag:educational。
IOI2025 纪念品/Souvenirs
很难想但充满提示性。
稍加观察其实可以发现一个若 \(P_x\) 被购买且 \(P_{x-1}\) 未被购买,则 \(P_{x-1}\gt P_x+lst\) 的性质,其中 \(lst\) 表示询问后剩余的硬币数。
事实上,这提示了这个题中越靠后的 \(P\) 限制越多,也越好确定的性质。
考虑从后往前确定 \(P\)。
当 \(N=1\) 时我们能够确定 \(P_0\),因此考虑询问一个绝对安全的询问,询问后假设第一个被购买的纪念品是 \(P_x\),则 \([x,N)\) 的纪念品构成子问题,一直问下去直到最后一个位置就可确定 \(P_{N-1}\)。
而在后面部分无法确定 \(P_x\) 的值,我们如何找到绝对安全的询问?其实只需要小于最大值并大于最小值,一个可能的取值为这次购买的所有纪念品价格的平均值。
于是这里形成一个递归问题,假设该递归问题能够帮我们确定一段后缀的所有 \(P\),现在考虑如何借此求解前半的值。
由于你需要完成该子问题之后才能确定该子问题的 \(P_0\)(上一层子问题中的 \(P_x\)),所以我们无法将左半规约成同样的子问题,一个做法是直接不管了,从上一层把所有已知的纪念品删去,重新求得一个平均值并再次向右递归,这样做显然每一次都会比上一次买到价格更高的纪念品,手模一下递归树也可以发现每个位置只可能成为一次 \(P_x\),如此多次操作总会使得 \(P_x\) 已知。
最后求完 \(P\) 之后再把每个纪念品补齐即可。
评分:9/10,tag:优美、好题。
CF1129E Legendary Tree
直接考虑 \(S=\{1\}\),\(T=U\setminus S\),然后取 \(x\) 就可以问出 \(x\) 的子树大小。
这样有叶子了,找树的形态的话,非常常规的想法就是找爹。
那么怎么找爹呢?我们从子树最小的非叶子节点找,这么一个点的儿子一定是叶子节点,在叶子节点中简单二分一个一个把儿子抽出来即可。
评分:7/10,tag:常规。
IOI2023 最长路程/Longest Trip
一个事实:有正环最长简单路径是 NP-Hard 问题。
在本题中就必须考虑这个问题如何得到多项式解法的,必然就和图的“路网密度”这一性质有关。
由于路网密度是针对三个点而言的,由于 \(D\ge 1\),所以三个点可以确定一条边。
每次考察一个极小范围,这其实是增量构造的常见形式,于是维护一条最长路径并尝试增量构造。
发现当 \(D\ge 2\) 时始终能够让一个点接入该路径,这解决了一个部分分。
而 \(D=1\) 时,有可能新的点无法接入路径,此时能够推出原路径是一个环,然而找不到用处。
我们不需要环,考虑把环断开,那么在知道这个点无法插入前,我们维护的是两条路径。
于是考虑真的维护两条路径,发现取出两条路径的各一个端点,则新点要么能插入两条路径中的一条,要么原来的路径可合并,新点自成一条路径。
最后我们得到这么两条路径之后尝试合并,如果端点能够合并则好说,否则可推出两条路径都是环,中间任何有一条边即可,这可以用两次二分。
此时询问次数是 \(2(n+\log n)\),超了,这很离谱。
详细计算一下发现限制大约是 \(\dfrac{3}{2}n+2\log n\) 的形状,那么一口气考虑两个点进行增量,分类讨论发现可行。
评分:9/10,tag:educational、好题、人类智慧。
WC2019 I 君的商店
数据范围对做法有极大提示性,但其实就算猜到是线性套一层二分也没啥用。
寻找询问的性质,单次询问几乎无法确定任何信息,我们希望找到能够确定信息的询问组合,这可能要用到多次询问。
当已知 \(v_a\le v_b\) 时,再进行一次组合,若另有 \(v_a+v_b\le v_c\),可立即确认 \(v_a=0\),无论 \(v_c\) 是何值均成立。
然而我们有必要考察反面,若 \(v_a+v_b\ge v_c\),该信息有用当且仅当 \(v_c=1\),者可以确认 \(v_b=1\)。
由于保证至少存在一个 \(1\),这样的 \(v_c\) 始终存在,不难想到线性扫一遍来获得最大值,这样能够找到这个 \(1\)。
此时的操作次数为 \(7n\),无法解决特殊的二分子任务。
考虑二分如何做,首先可以通过询问 \(v_1\) 与 \(v_n\) 的大小关系确定是单增还是单减,默认是单增的话一定有 \(v_n=1\),这样同上我们每 \(3\) 次询问确认一个位置,对应进行二分即可。
将两者融合,在得到 \(v_c=1\) 之前,我们仍有 \(v_b\ge v_c\) 成立,这里能够构造出一个单调递增的序列,在 \(v_b\) 替换为新的最大值之后,将 \(v_c\) 放入待确定的单调序列中。
顺势求得最大值后,对剩余部分进行二分(这里注意里面可能没有 \(1\)),问题得到解决。
细节很多,而且需要不少特判。
评分:7/10,tag:难写、细节、人类智慧。
CF1292E Rin and The Unknown Flower
观察到越长的序列越赚,但是此时得到的信息量太少了,这很不好。
我们想要找到某种字符的所有出现位置,比如找 C
,一种想法是直接问 C
,但这太贵了。
观察发现如果你分别询问 CC
、CH
和 CO
,代价只有 \(0.75\) 而可以确定几乎全部的 C
,这是很优的。
不过我们只能对一个字符执行该操作,因为我们只有 \(1.4\) 的能量,而两个字符的操作需要 \(1.5\)。
于是考虑在得到一个字符的几乎全部信息之后,我们还可以再搞些什么。
人类直觉地,问完 C
问 OH
嘛,于是我们将 OH
和 HO
都问了,这个时候你会发现这么个性质:
除了开头的连续段和结尾字符,未确认的位置一定位于连续段中,和前后的字符相同,这是因为所有 C
都被问出来了,除了开头以外,任何 HC
和 OC
都可以被识别,所以所有的分界处都被确认了。
只需要确认开头一段和末尾的那个字符,由于其它字符均已确定,所以只需询问一个长为 \(n-1\) 的串即可确认开头,之后再询问一个长为 \(n\) 的串就可确定结尾。
此时代价为 \(1.25+\dfrac{1}{(n-1)^2}+\dfrac{1}{n^2}\),当 \(n\ge 5\) 时该值 \(\le 1.3525\),可行。
而当 \(n=4\) 时,这样的方案需要的代价达到了 \(1.4236111\cdots\),超出了限制。
不过既然只有这么一种情况,对于小数据直接特判就可以了,暴力枚举可以找到方法。
评分:5/10,tag:丑陋、暴力、分讨、枚举、人类智慧。
CF1924F Anti-Proxy Attendance
原本的题解做法长得丑,不提了。
考虑 \(102\rightarrow 55\) 次的加强版,先从理论下手分析一下这个题。
这个其实是很一类的想法,如何根据已有信息,从若干可能方案中分辨出正确的方案。
比如 Wordle 也是这种类型的,前面很多交互题也都是这种类型的。
而这个题,我们要从这里下手,展现这个思想的强大威力。
通过一点信息论的基础知识,我们知道描述混乱程度的熵,每次询问相当于为我们减少一些信息熵,这也可用势能来大致理解。
当熵足够小,状态就足够确定,我们尝试来刻画本题中的熵。
考虑一个来自 CF1746E 的思路,我们可以对每个人记录交互库的说谎情况,如果一个人缺席时交互库的回答不满足要求,可以确定这个人没有缺席,其熵减至 \(0\)。
详细来说,我们记录 \(S_i\) 表示若第 \(i\) 个人缺席,交互库的回答序列是否正确。
比如第 \(1\) 个人缺席,而交互库在前两次询问中都说第 \(1\) 个人没有缺席(这是可以通过询问推断出来的),那么 \(S_1=\texttt{00}\)。
基于此,我们尝试刻画暂未确认是否缺席的人的熵,不难发现一个人的说谎序列只有最后两位有用。
我们尝试给这些位置赋予一个熵值,注意到 \(\texttt{0}\) 与 \(\texttt{1}\) 对称,不妨设 \(\texttt{00}\) 和 \(\texttt{11}\) 的熵是 \(1\),\(\texttt{01}\) 与 \(\texttt{10}\) 的熵设为 \(x\),在之后,我们将分析出 \(x\) 的最优取值以及其对应的策略。
稍加分析,我们得到答案的必要条件是最后对于每个 \(S_i\) 的结尾两个字符分析得到的熵的总和 \(E\) 在 \(2,2x\) 组成的区间内,之后所述 \(E\) 即为此定义。
我们现在分析每次询问之后,\(S_i\) 的熵的变化情况:
\(\texttt{00}\) | \(\texttt{01}\) | \(\texttt{10}\) | \(\texttt{11}\) | |
---|---|---|---|---|
往后加入 \(\texttt{0}\) | 炸了 | \(x\) | \(1\) | \(x\) |
往后加入 \(\texttt{1}\) | \(x\) | \(1\) | \(x\) | 炸了 |
注意,\(S_i\) 炸了之后,其熵将保持为 \(0\)。
现在考虑如何询问使得熵变得尽可能小,由于交互库可能会选择性回答真话或者假话,不妨设交互库回答真话和假话后 \(E\) 的值分别变为 \(E_1\) 和 \(E_0\),则交互库的决策一定是选择较大的那个。
这是因为当熵足够低,达到上述的必要条件后,我们一定能够经过常数次询问获得最终答案,这可以用特判手段,也可以通过一些证明得到我们最终的做法在这部分是正确的(本文没有进行这部分证明)。
也正因此,交互库无法避免熵低时选手得到答案,就只能通过避免熵减小过快来增加询问次数。
于是我们的策略也非常简单明了:选择 \(E_0\) 与 \(E_1\) 中最大值最小的询问区间进行询问。
而 \(E_0\) 与 \(E_1\) 的最大值取决于 \(x\),据上述表格,我们可以分析出,对于上述四种情况,\(E_0\) 和 \(E_1\) 的变化与原本的 \(E\) 的比值:
\(\texttt{00}\) | \(\texttt{01}\) | \(\texttt{10}\) | \(\texttt{11}\) | |
---|---|---|---|---|
\(\frac{E_0}{E}\) | 炸了 | \(1\) | \(\frac{1}{x}\) | \(x\) |
\(\frac{E_1}{E}\) | \(x\) | \(\frac{1}{x}\) | \(1\) | 炸了 |
实际上,由于四种情况可能会有极端的构造数据将所有人的序列末尾都设置为同一个串,因此我们的最优解应当使得上述四种情况的最大值最小。
到这里问题仍然十分复杂,但是这里有个非常巧合的事情。
考虑一个看上去很不对的想法,我们将 \(E_0\) 与 \(E_1\) 的平衡和上面四种情况的平衡分开考虑。
假设我们始终能够完全平衡 \(E_0\) 和 \(E_1\),则后半的平衡只需考虑 \(E_0+E_1\) 最小,这样列出方程 \(x=1+\dfrac{1}{x}\),不难解得 \(x=\phi=\dfrac{1=\sqrt{5}}{2}\)。
如此取 \(x\),倒回去考虑 \(E_0\) 与 \(E_1\) 的平衡,注意到一个前缀和其对应的后缀的 \(E_0-E_1\) 的值互为相反数,而相邻前缀之间 \(E_0\) 和 \(E_1\) 的变化均为 \(\mathcal{O}(1)\) 或 \(\mathcal{O}(x)\) 的,因此总存在一个前缀,询问该前缀得到的 \(|E_0-E_1|\) 的值是一个常数。
因此,我们将整体串起来了,非常巧合地发现所有信息都能够平衡,于是策略也出来了,只需找到这样的前缀即可。
此时每次我们都可以使当前的势能 \(E\) 变为 \(\max\{E_0,E_1\}\approx\dfrac{\phi}{2}E\),总的询问次数也就是 \(\mathcal{O}(\log_{\frac{2}{\phi}}n\phi)\) 的(初始势能最大为 \(nx=n\phi\))。
注意到上述论述是充分的,即过程中每一步都已达到理论最优,所以不存在比该做法更优秀的做法。
评分:10/10,tag:信息论、势能分析、神题。
CF1919I Grid Game
全场唯一真屎……
注意到 \(n,m\) 均为奇数是容易的,因为交互库会多一次操作,大部分构造都能通过。
而 \(n,m\) 有偶数时,我们后手要吃大亏,这时候只能想办法构造一些 dead lock 让交互库被迫选大数。
有个 T 形构造如此图:
稍微想想很快会发现这个东西确实是个 dead lock,交互库直接吃大亏。
然而这东西很难完整填补整个矩阵,而且在其不位于边界时会失效,这很不好。
可能会想着将其改良成十字形,但那更加难放,就不在考虑范围内了。
那么这时候可以考虑一个经典的二分图常出现的构造:骨牌。
一个 \(1\times 2\) 的骨牌上放两个相邻的数,这样交互库拿了一个我们立刻拿另一个,保证我们最多吃亏 \(1\)。
而骨牌配合 T 形足以填补任意形状的矩阵了,可以经过精细计算得到这样的构造在 \(n,m\ge 4\) 的时候一定足够赚。
代码肉眼可见的难写。
评分:2/10,tag:屎。
构造不像构造,交互不像交互,你不如搞成提交答案题,纯纯大粪一坨,给你一分是看在我没想出来 T。