1 条题解

  • 0
    @ 2025-10-28 9:43:55

    题意回顾

    • 环形密码盘,nn 格,每格一个数字 Ai[0,9]A_i \in [0,9] 和一个运算符 Ci{+,}C_i \in \{+,*\}
    • 解密:从起点 pospos 开始,生成数组 BB
      • B0=AposB_0 = A_{pos}
      • $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}$
    • BB 视为环,找最远的零区间(连续 00 段)。
    • 距离:零区间中任意 00B0B_0 的环上最短距离的最小值。
    • 操作:修改某格数字和运算符,或询问从某点开始的解密结果。

    数据范围:n,m105n, m \leq 10^5


    核心思路

    1. 函数复合视角

    每个位置的运算可以看作一个函数 fi:Z10Z10f_i: \mathbb{Z}_{10} \to \mathbb{Z}_{10}

    • Ci=+C_i = '+',则 fi(x)=(x+Ai)mod10f_i(x) = (x + A_i) \bmod 10
    • Ci=C_i = '*',则 fi(x)=(x×Ai)mod10f_i(x) = (x \times A_i) \bmod 10

    解密过程就是函数复合: $ B_k = f_{pos+k} \circ f_{pos+k-1} \circ \cdots \circ f_{pos+1}(A_{pos}) $


    2. 仿射变换与复合

    实际上,这两种运算在模 1010 下构成仿射变换f(x)=(mx+a)mod10 f(x) = (m \cdot x + a) \bmod 10

    • 对于加法:m=1,a=Aim=1, a=A_i
    • 对于乘法:m=Ai,a=0m=A_i, a=0

    复合规则:
    F1(x)=(m1x+a1)mod10F_1(x) = (m_1 x + a_1) \bmod 10F2(x)=(m2x+a2)mod10F_2(x) = (m_2 x + a_2) \bmod 10,则: $ 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. 线段树维护

    用线段树维护任意区间 [l,r][l, r] 的复合函数 (ml,r,al,r)(m_{l,r}, a_{l,r})

    建树
    叶子 ii:若 Ci=+C_i = '+',则 (1,Ai)(1, A_i);若 Ci=C_i = '*',则 (Ai,0)(A_i, 0)

    合并
    对于节点 [l,r][l, r],设左子 [l,mid][l, mid](mL,aL)(m_L, a_L),右子 [mid+1,r][mid+1, r](mR,aR)(m_R, a_R),则: $ m = m_R \cdot m_L \bmod 10,\quad a = (m_R \cdot a_L + a_R) \bmod 10 $

    修改O(logn)O(\log n) 更新叶子并上推。


    4. 零区间判定

    从起点 pospos 开始,B0=AposB_0 = A_{pos}
    BkB_k 是前 kk 步复合函数作用在 AposA_{pos} 上的结果: $ B_k = m_{1..k} \cdot A_{pos} + a_{1..k} \pmod{10} $ 其中 (m1..k,a1..k)(m_{1..k}, a_{1..k}) 是区间 [pos+1,pos+k][pos+1, pos+k] 的复合函数(环状处理)。

    因此: $ B_k = 0 \iff m_{1..k} \cdot A_{pos} + a_{1..k} \equiv 0 \pmod{10} $


    5. 环上最远零区间查找

    距离定义:在长度为 nn 的环上,位置 kk 到位置 00 的距离为: dist(k)=min(k,nk) \text{dist}(k) = \min(k, n-k) 零区间 [L,R][L, R] 的距离为 mink[L,R]dist(k)\min\limits_{k \in [L,R]} \text{dist}(k)

    查找策略

    1. 找出所有满足 Bk=0B_k = 0kk(即满足同余条件的 kk
    2. 将这些 kk 按环上位置排序,找出所有连续零区间
    3. 对每个零区间计算其到 00 的距离,取最大值

    不需要检查所有 kk,只需在可能成为最远零区间的候选位置检查。


    算法流程

    初始化

    • 读入 n,mn, m 和密码盘数据
    • 建线段树

    修改操作

    • 更新叶子节点的 (m,a)(m, a)
    • 上推合并

    询问操作

    1. 从起点 pospos 开始,B0=A[pos]B_0 = A[pos]
    2. 如果 B0=0B_0 = 0,则包含 B0B_0 的零区间距离为 00
    3. 计算环上对面区域(距离 n/2\approx n/2)的复合函数
    4. 二分查找该区域附近的零区间
    5. 检查 B0B_0 附近的零区间
    6. 取所有零区间距离的最大值
    7. 如果没有零区间,输出 1-1

    复杂度分析

    • 建树:O(n)O(n)
    • 修改:O(logn)O(\log n)
    • 询问:O(log2n)O(\log^2 n)(二分查找 + 线段树查询)
    • 总复杂度:O(n+mlog2n)O(n + m \log^2 n),可过 10510^5

    总结

    1. 函数复合:将递推转化为仿射变换复合
    2. 线段树O(logn)O(\log n) 查询任意区间复合函数
    3. 模运算性质:利用模 1010 简化计算
    4. 环上二分:在关键区域查找最远零区间

    通过数学转化与数据结构结合,将朴素 O(nm)O(nm) 优化到 O(mlog2n)O(m \log^2 n),解决了大数据范围的问题。

    • 1

    信息

    ID
    4403
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    4
    已通过
    1
    上传者