通信题
问题
你尝试在一块信息介质上记录下一个 \(1\) 到 \(n\) 之间的整数 \(x\),每次可以写入一个比特 \(0\) 或 \(1\),不过因为一些原因,实际写入的比特不一定和发出的指令相同,但可以保证任意连续的两次写入中,至少有一个是正确写入的,每次操作后可以查看实际写入状态。在另外一个场景中你得到了之前写下的信息,要还原出 \(1\) 到 \(n\) 之间的数 \(x\),由于信息丢失,\(x\) 可能存在 \(2\) 种可行值,此时要找出这两个可行值。对于确定的 \(n\),我们需要的信息比特量最少是多少?
思考
先考虑找到一个能用的策略。
注意到 \(01\) 串 0000
0110
1111
在受到扰动(翻转一些位)后仍然可以保留一些性质,扰动后 0000
不可能包含 11
,0110
必然包含 00
或 11
,1111
不可能包含 00
。可以发现最终写入的串必然满足三个中的两个,于是可以确定对应的原信息一定不是三个中剩下的那一个。
于是我们可以维护一个 \(x\) 可能存在的集合 \(S\),开始 \(S=\{1,2,...,n\}\),每次将 \(S\) 尽量均分成三个集合 \(S_1,S_2,S_3\),\(x\) 实际在哪个集合中就分别用 0000
0110
1111
表示,根据实际写入的信息能够知道 以后在解码时可以排除掉 \(S_1,S_2,S_3\) 中的哪个集合,然后将 \(S\) 更新为另外两个集合的并即可。
最后 \(|S|\leq 2\) 时 解码方就知道是哪两种可行值了。每轮之后候选集合的规模都为之前的 \(\frac{2}{3}\),于是比特量为 \(4\log_{1.5}n\),这里主要考虑 \(n\) 足够大甚至 \(n\rightarrow \infty\) 时的情况,因此忽略取整等问题。
可以发现上面的方案中编码方和解码方的工作其实是同步进行的,在实际操作中是双方有着同一套问答体系,只不过编码时只回答问题,解码时只获取问题答案,具体问的问题双方都默默过了一遍。
这启发我们对问题做一个转化,将写入和读取换为同步的问答,即:
已知 \(x\) 在 \(1\) 到 \(n\) 之间,你每次要向对方询问一个有关 \(x\) 的问题,对方会返回一个 \(0\) 或 \(1\) 作为答复,答复不一定为真,但保证连续两次回答中至少有一个是真的,请你用尽可能少的询问次数找到 \(x\) 的 \(2\) 种可行值。
这样 \(x\) 存在两种可能性就是可以理解的了,对方只需要在奇数次询问按照 \(x\) 如实回答,偶数次询问按照另一个数 \(y\) 回答,你就只能确定实际的数是 \(x\) 或者 \(y\) 了。
“询问一个有关 \(x\) 的问题” 太抽象了,可以发现这等价于给定一个集合 \(T\),询问 \(x\) 是否在里面。
解决
考虑维护一对集合 \((A,B)\),表示若上一次对方的回答为 真/假 时 \(x\) 的候选集合为 \(A\) / \(B\) 。设这次询问的集合为 \(C\),那么根据答复分类讨论可以得到
其中若这一次答复为假,则上次必须为真,否则上次真假皆可能。
若要研究询问次数,则我们只关心集合的大小,\(|A|+|B|\) 什么时候 \(\leq 2\),设 \(n=|A|,m=|B|\),\(a=|A\cap C|,b=|B\cap C|\),则
设 \(f(n,m)\) 表示 \(A,B\) 规模分别为 \(n,m\) 时所需要的最少询问数,则在 \(n+m>2\) 时有
初始 \(A=\{1,2,...,n\}\),\(B=\empty\),所以我们关心的就是 \(f(n,0)\) 的值。
考虑将每次 \(\text{ans}=0/1\) 的情况画成一棵二叉决策树,根节点即 \(f(n,0)\),现在要求树的高度。不失一般性地,假设所有情况下的询问次数都相同,否则将次数较少的情况后面加上若干次询问 \(C=\empty\) 补齐。根据递推式,注意到 \(f(a,b)\) 的后继节点 \(f(a_1,b_1),f(a_2,b_2)\) 必然满足 \(a_1+a_2=a+b,\;b_1+b_2=a\),因此统计同一层上所有 \(A\) 的大小之和与 \(B\) 的大小之和,应是这么变化的
可以发现这就是斐波那契数列的递推:\((\text{Fib}(i+1)+\text{Fib}(i),\text{Fib}(i+2))=(\text{Fib}(i+2),\text{Fib}(i+1))\),而这里初始项为 \((n,0)\),于是乎第 \(i\) 层的总大小为 \(n\cdot\text{Fib}(i+2)\) 。众所周知
记 \(\phi =\frac{1+\sqrt 5}2\),则 \(\text{Fib}(i)\) 在 \(i\) 足够大时趋向 \(\phi^i/\sqrt 5\) 。考虑二叉树的最后一层,所有叶子节点都满足 \(|A|+|B|\leq 2\),设树高为 \(h\),最后一层共 \(2^h\) 个节点,则这一层的总大小 \(\leq 2\cdot 2^h\),因此
于是我们所需要的比特量的下界为 \(\displaystyle \log_{\Large\frac{2}{\phi}}\frac{n\phi^2}{2\sqrt 5}\)。
具体方案的构造:每次取 \(a=\frac{n}{2},b=\frac{m}{2}\),则无论 \(\text{ans}=0/1\) 规模都会变为 \((\frac{n+m}2,\frac{n}2)\),最终 \(n+m\leq 2\),容易得到最后第 \(i\) 次操作之后 \(\displaystyle n+m=\frac{n\cdot \text{Fib}(i+1)}{2^i}\leq 2\),关于 \(i\) 的不等式与上面的完全相同,因此操作次数即比特量下界。
在实际操作中可以令 \(a=\lceil\frac{n}{2}\rceil,b=\lfloor\frac{m}{2}\rfloor\),这样的询问数在渐进意义上是达到下界的。若要精确达到最小值,需要 \(O(n^4)\) 递推计算 \(f(n,0)\),\(a,b\) 的选取按照 \(\arg\min\) 来。在具体实现中,\(n=10^5\) 时可以做到最多用 \(53\) 个比特,\(n=10^9\) 时最多 \(96\) 个,和下界吻合的很好。
推广
如果将条件改为「保证连续 \(k\) 次写入中至少有一个是正确的」呢?
此时最终确定下来的可能值的个数为 \(2^{k-1}\),考虑沿用前面的策略,我们对前 \(k-1\) 个答复的所有真假可能性维护 \(2^{k-1}\) 个候选集合 \((A_{11..1},A_{01..1},...,A_{00..0})\) (低位在前),比如看 \(k=3\) 的情况
还是看二叉树上集合大小之和的变化,是 \((a_{11},a_{01},a_{10},a_{00})\rightarrow (a_{11}+a_{10},a_{11}+a_{10},a_{01}+a_{00},a_{01})\),也就是 \(a'_s=a_{s/2}+a_{s/2+2^{k-2}},\;a'_0=a_1\) 。看看 \(k=4\) 的情况(把初始的 \(n\) 换为 \(1\)):
这个变换用矩阵是好刻画的
不过对于一般的 \(k\),\(M\) 的特征值不太好求,从这个角度求出 \(\{a\}\) 具体的通项是困难的。
注意到从 \(2k-2\) 项开始,\(a_s\) 的值开始按照二进制含 \(1\) 的最高位分层组,这一点容易归纳证明。对于线性常系数递推式,若 \(M\) 存在一个特征值的绝对值比其它的都大,则当项数 \(p\rightarrow \infty\) 时,前后两项对应位的比值会趋向于一个定值,设 \(Q\) 为 \(M\) 的一个对角矩阵,\(M=TQT^{-1}\),\(A_p\) 是第 \(p\) 轮操作后 \(\{a\}\) 组成的行向量,则 \(A_0\times M^p=A_p\iff A_0\times TQ^pT^{-1}=A_p\),\(Q^p\) 中绝对值最大者会占主导地位,前后项比例会趋向这个值。
假设对于 \(A_p\) 这个比例存在,则 \(\{a\}\) 中各项的大小关系也会趋向固定, 设 \(A_p=(c\;\;c\;\;c\;\;c\;\;b\;\;b\;\;a\;\;1)\),则 \(A_{p+1}=(b\!+\!c\;\;b\!+\!c\;\;b\!+\!c\;\;b\!+\!c\;\;a\!+\!c\;\;a\!+\!c\;\;1\!+\!c\;\;c)\),根据比例有
对于一般的 \(k\),容易得到比例 \(\lambda\) 即 \(1+x+x^2+...+x^{k-1}=x^k\) 的正实数根,由于正根唯一且不存在绝对值更大的负实数根,因此比例极限存在,即 \(\lambda\) 。
回到 \(k=4\) 的情况,可以发现确实在 \(i\geq 2k-2\) 时,\(A_i=A_{i-1}+A_{i-2}+A_{i-3}+A_{i-4}\),与方程吻合。进一步地,设 \(f_i\) 为 \(A_i\) 的各项之和,可以得到
众所周知,通过「生成函数部分分式分解」或「矩阵对角化」可以得到 \(f_i\) 的通项公式为 \(f_n=\sum_{i=0}^{k-1}c_i\lambda_i^n\),\(\lambda_0,..,\lambda_{k-1}\) 为 \(1+x+..+x^{k-1}=x^k\) 的 \(k\) 个根,设 \(c\) 为唯一正实数根 \(\lambda\) 系数,则 \(n\) 足够大时,\(f_n\rightarrow c\cdot \lambda^n\) 。
在二叉树的最后一层应有每个节点的大小 \(\leq 2^{k-1}\),现在我们得到第 \(h\) 层的总大小 \(n\cdot f_h\sim n\cdot c\cdot \lambda^h\),于是
最终我们的结果是:
令 \(\lambda\) 为 \(1+x+...+x^{k-1}=x^k\) 正实数根,则最少需要的比特数量为 \(\displaystyle \log_{\Large \frac{2}{\lambda}}n-\frac{k}{1-\log_2\lambda}+\epsilon(k)\),其中 \(\epsilon(k)\) 为只与 \(k\) 有关的常数。
具体方案还是所有候选集合各取一半拼成询问集合,渐进意义下可达下界。
\(c\) 明显很复杂,因此 \(\epsilon(k)\) 很难展开,意义也不大,但是对于固定的 \(k\),是可以算出具体值的。
背景
IMO2012 P3:要求证明最终可能集合大小 \(\leq 2^{k-1}\),且存在方案使得集合大小 \(\geq 1.99^{k-1}\)
BOI2022 P4:\(n\leq 10^9,k=2\) 的情形,要求使用比特数 \(\leq 100\)
CF1746E2:\(n\leq 10^5,k=2\) 的情形,要求使用比特数 \(\leq 53\)
Searching with local constraints on error patterns:\(1994\) 年的论文,讨论的是连续 \(k\) 个中至多有一个错的情况。