1 条题解
-
0
题意回顾
- 环形密码盘, 格,每格一个数字 和一个运算符 。
- 解密:从起点 开始,生成数组 :
- $B_x = \begin{cases} (A_{(pos+x)\bmod n} + B_{x-1}) \bmod 10, & C_{(pos+x)\bmod n} = '+' \\ (A_{(pos+x)\bmod n} \times B_{x-1}) \bmod 10, & C_{(pos+x)\bmod n} = '*' \end{cases}$
- 将 视为环,找最远的零区间(连续 段)。
- 距离:零区间中任意 到 的环上最短距离的最小值。
- 操作:修改某格数字和运算符,或询问从某点开始的解密结果。
数据范围:。
核心思路
1. 函数复合视角
每个位置的运算可以看作一个函数 :
- 若 ,则
- 若 ,则
解密过程就是函数复合: $ B_k = f_{pos+k} \circ f_{pos+k-1} \circ \cdots \circ f_{pos+1}(A_{pos}) $
2. 仿射变换与复合
实际上,这两种运算在模 下构成仿射变换:
- 对于加法:
- 对于乘法:
复合规则:
设 ,,则: $ F_2 \circ F_1(x) = m_2(m_1 x + a_1) + a_2 = (m_2 m_1) x + (m_2 a_1 + a_2) \bmod 10 $ 即新函数参数为: $ m' = m_2 m_1 \bmod 10,\quad a' = (m_2 a_1 + a_2) \bmod 10 $
3. 线段树维护
用线段树维护任意区间 的复合函数 。
建树:
叶子 :若 ,则 ;若 ,则 。合并:
对于节点 ,设左子 为 ,右子 为 ,则: $ m = m_R \cdot m_L \bmod 10,\quad a = (m_R \cdot a_L + a_R) \bmod 10 $修改: 更新叶子并上推。
4. 零区间判定
从起点 开始,。
是前 步复合函数作用在 上的结果: $ B_k = m_{1..k} \cdot A_{pos} + a_{1..k} \pmod{10} $ 其中 是区间 的复合函数(环状处理)。因此: $ B_k = 0 \iff m_{1..k} \cdot A_{pos} + a_{1..k} \equiv 0 \pmod{10} $
5. 环上最远零区间查找
距离定义:在长度为 的环上,位置 到位置 的距离为: 零区间 的距离为 。
查找策略:
- 找出所有满足 的 (即满足同余条件的 )
- 将这些 按环上位置排序,找出所有连续零区间
- 对每个零区间计算其到 的距离,取最大值
不需要检查所有 ,只需在可能成为最远零区间的候选位置检查。
算法流程
初始化
- 读入 和密码盘数据
- 建线段树
修改操作
- 更新叶子节点的
- 上推合并
询问操作
- 从起点 开始,
- 如果 ,则包含 的零区间距离为
- 计算环上对面区域(距离 )的复合函数
- 二分查找该区域附近的零区间
- 检查 附近的零区间
- 取所有零区间距离的最大值
- 如果没有零区间,输出
复杂度分析
- 建树:
- 修改:
- 询问:(二分查找 + 线段树查询)
- 总复杂度:,可过
总结
- 函数复合:将递推转化为仿射变换复合
- 线段树: 查询任意区间复合函数
- 模运算性质:利用模 简化计算
- 环上二分:在关键区域查找最远零区间
通过数学转化与数据结构结合,将朴素 优化到 ,解决了大数据范围的问题。
- 1
信息
- ID
- 4403
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 4
- 已通过
- 1
- 上传者