1 条题解
-
0
Math Division 详细题解
题目分析
核心题意
给定一个二进制表示的正整数 (长度为 ,最高位为 ),每次操作可以等概率选择两种操作之一:
- 向下取整除以 :
- 向上取整除以 :
操作直到 停止,求操作次数的数学期望,答案对 取模(分数取模需计算乘法逆元)。
关键观察
- 二进制长度为 的数,纯向下取整操作到 的固定次数是 次(比如 ,长度 ,纯向下操作:,共 次)。
- 二进制中末尾的 会额外增加操作次数的期望,这是唯一影响期望的变量。
数学推导
定义
设:
- :数字 操作到 的期望次数
- 模:, 的模逆元 (因为 )
递推公式
对任意 :
$$E(x) = 1 + \frac{1}{2}E\left(\lfloor \frac{x}{2} \rfloor\right) + \frac{1}{2}E\left(\lceil \frac{x}{2} \rceil\right) $$解释:当前操作计数 + 两种操作的期望平均。
二进制特性简化
将 写成二进制:
- 若 是偶数(最低位为 ):$\lfloor \frac{x}{2} \rfloor = \lceil \frac{x}{2} \rceil$,此时 ,无额外期望。
- 若 是奇数(最低位为 ):$\lceil \frac{x}{2} \rceil = \lfloor \frac{x}{2} \rfloor +1$,推导得: 奇数会固定多 次期望操作。
最终结论
- 基础操作次数:(二进制长度减一)。
- 额外期望:从最低位到次高位,每遇到一个 ,就累加 ( 是该位到最低位的距离)。
- 总期望:
( 是二进制字符串第 位,下标从 开始)
标程代码解析
核心代码逻辑
// 初始化答案为 0 ll ans = 0; // 从二进制最低位(最后一位)遍历到次高位 for (ll i = n;i > 1;i -= 1) // 遇到 1 就加 1,然后乘以 1/2(模逆元) ans = (ans + (s[i] == '1')) * inv2 % mod; // 总答案 = 基础次数 + 额外期望 printf("%lld\n",(n - 1 + ans) % mod);逐行解释
- 遍历方向:从二进制最后一位(最低位)到第二位(次高位),最高位永远是 且不影响额外期望。
- 累加规则:
- 每一位是 ,先 ;
- 然后整体 (等价于 ,模运算中用逆元实现)。
- 这个过程自动实现了 的求和(递推计算等比数列)。
- 最终结果:基础次数 加上额外期望
ans,取模输出。
样例验证(第一组样例)
输入:
3 110- ,二进制串
- 基础次数:
- 遍历计算
ans:- : →
- : →
- 总期望:
- 模运算:$\frac{5}{2} \equiv 5 \times 500000004 \equiv 500000006 \pmod{10^9+7}$,与样例输出一致。
模运算关键知识点
- 分数取模:题目要求输出 ,等价于 。
- 逆元计算: 的逆元 ,是固定常量。
- 取模规则:每一步运算都取模,防止溢出。
复杂度分析
- 时间复杂度:,所有测试 case 总长度不超过 ,符合时间限制。
- 空间复杂度:,存储二进制字符串。
总结
- 核心规律:二进制长度决定基础操作次数 ,低位的 带来额外期望。
- 计算技巧:逆序遍历 + 递推乘 ,高效计算额外期望和。
- 模运算:分数取模使用乘法逆元,固定 。
- 1
信息
- ID
- 6389
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者