# 数据恢复 题解 解法署名:出题人解法通过一个足够大的模数恢复缺失前缀;Codex(GPT-6)采用双模数与中国剩余定理实现精确整数恢复。 ## 解法比较 ### 出题人解法:一个足够大的模数 设后缀字符串长为 $k$ 、表示整数 $s$ ,缺失前缀为 $x$ ,则 $n!=x10^k+s$ ,且 $0\le x<10^{15}$ .出题人解法取质数 $M=7\cdot2^{52}+1=31525197391593473$ ,分别计算阶乘和后缀的余数,再求 $$x\equiv(n!-s)(10^k)^{-1}\pmod M$$ 因为 $M$ 与 $10$ 互质,逆元存在;又因为 $x10^{15}$ . 对模数 $t\in\{p,q\}$ ,依次相乘计算 $n!\bmod t$ ;逐位扫描后缀,按“当前余数乘十加新数字”求 $s\bmod t$ .用快速幂求 $10^k\bmod t$ ,再用费马小定理计算其逆元,得到 $$r_t=(n!-s)(10^k)^{-1}\bmod t$$ 所有余数都正规化到 $0,\ldots,t-1$ .输入中的前导零不影响取模,但必须保留在最终拼接的字符串中。 ## 合并与唯一性 先令 $x=r_p+pu$ ,再使它满足模 $q$ 的条件: $$u=(r_q-r_p)p^{-1}\bmod q$$ 取 $0\le u0$ ,先输出它,再原样输出后缀;若 $x=0$ ,只输出后缀。合法输入中,$x=0$ 意味着整个阶乘已经在后缀中,不会产生额外前导零。当 $k=0$ 时,后缀为空且 $s=0$ ,直接输出恢复的阶乘。$0!$ 和 $1!$ 的连乘初值都是 $1$ . ## 实现与复杂度 设 $P=\max(p,q)$ .在这些模数可用机器整数表示的模型下,时间为 $O(n+k+\log(k+1)+\log P)$ ,空间为 $O(k+1)$ .保存后缀是为了输出;参考程序不构造大整数阶乘。 模乘的两个因子都小于 $P$ ,乘积小于 $P^2<2^{63}$ ;中国剩余定理的合并结果小于 $pq<2^{63}$ .因此标准 C++17 的有符号 64 位整数足够,不需要浮点近似或编译器扩展。 ## 验证 小规模使用 Python 的整数阶乘直接比较完整输出;正式输入也逐字与整数阶乘比较。覆盖 $k=0$ 、$k=D$ 、最大十五位前缀、后缀前导零和最大 $n$ . 性能测量见[评测环境与性能](../../../docs/评测环境与性能.md)。