【2 月小记】Part 1: LCOI-R1 比赛总结

LCOI-R1 比赛总结

T1

考点

数学、推式子

题意

给你有一个数 \(cur\),初始 \(cur = s\)

定义一次操作为

\[cur \leftarrow \begin{cases} cur - a, &cur \ge t \\ cur + b, &cur < t \end{cases} \]

\(n\) 次操作后 \(cur\) 的值。

要求 \(O(1)\) 时间复杂度内计算。

简析

注意到因为 \(cur\) 的变化仅与它和 \(t\) 之间的相对位置关系有关,所以我们不妨把 \(s\)\(t\) 平移一下。

定义差值

\[d = cur - t \]

于是操作变为

\[d \leftarrow \begin{cases} d - a, & d \ge 0 \\ d + b, & d < 0 \end{cases} \]

如今问题转化为:已知 \(d_0 = s - t\),进行 \(n\) 次上述规则的操作,求 \(d_n\)(由于我们有 \(cur = d_n + t\),所以只需要输出它加上 \(t\) 的结果即可)。

观察 \(d\) 的变化:

  • 如果 \(d \ge 0\),它会不断减 \(a\),直到 \(d < 0\)

  • 如果 \(d < 0\),它会不断加 \(b\),直到 \(d \ge 0\)

由此可知,\(d\) 的值先会一直增加或减少,然后进入区间 \([-a,\ b-1]\),在其中循环。因此,我们断言,\(d\) 的变化有两个阶段:还没进入循环区间内的阶段(前置阶段),以及进入循环区间内在区间内循环的阶段(循环阶段)。

A. 前置阶段

不妨设:想要进入循环区间内,所需要的操作次数为 \(cnt\)

  • \(d_0 \ge 0\) 时,有

    \[cnt = \Big\lfloor \frac {d_0} a \Big\rfloor + 1 \]

    • 如果 \(cnt > n\),直接得

      \[d_n = d_0 - na \]

    • 否则先执行 \(cnt\) 次操作

      \[d_{cnt} = d_0 - cnt \cdot a \]

      剩下的 \(n - cnt\) 次操作将进入循环阶段。

  • 类似地,当 \(d_0 < 0\) 时,有

    \[cnt = \Big\lceil \frac{-d_0} b \Big\rceil \]

    • 如果 \(cnt > n\),直接得

      \[d_n = d_0 + nb \]

    • 否则先执行 \(cnt\) 次操作

      \[d_{cnt} = d_0 + cnt \cdot b \]

      剩下的 \(n - cnt\) 次操作将进入循环阶段。

B. 循环阶段

经过上面处理,我们已经得到 \(d_{cnt}\) 和剩余操作次数 \(n - cnt\),并且 \(d_{cnt}\) 已经在循环区间 \([-a,\ b-1]\) 内。

\(d\) 进入区间 \([-a, b-1]\) 后,操作规则为

\[d \leftarrow \begin{cases} d - a, &d_i \ge 0\\ d + b, &d_i < 0 \end{cases} \]

记这个区间的长度为 \(m = a+b\)

  • \(d \ge 0\) 时,有

    \[d \leftarrow d - a \]

    \[d - a = d + b - m \]

    这相当于把 \(d\) 先加上 \(b\),然后用 \(m\) 做减法来调整 \(d\) 的值。

  • \(d < 0\) 时,有

    \[d \leftarrow d + b \]

    容易看出,它不需要用 \(m\) 调整。

综上所述,在循环阶段,每次操作相当于给当前值 \(d\) 加上 \(b\),然后对 \(m\) 取模,来将 \(d\) 调整到原来的循环区间内。也就是说,我们通过一步转化,使操作变为了

\[d \leftarrow \begin{cases} d + b - m, &d \ge 0 \\ d + b, & d < 0 \end{cases} \]

进一步地,当我们有 \(i\) 次操作的时候,情况又会变为什么样?

考虑计算累积位移,不考虑循环区间边界的限制,我们有

\[x = d + (n - cnt) \cdot b \]

然后,将累计位移取模到一个周期内,记

\[r = x \bmod m \in [0,\ m - 1] \]

最后调整到循环区间内,有

\[d \leftarrow \begin{cases} r, &r < b \\ r - m, &r \ge b \end{cases} \in[-a,\ b - 1] \]

记上面这种对 \(d\) 的特殊运算为 \(\text{Mod}\),那么有

\[d_n \leftarrow (d_{cnt} + (n - cnt) \cdot b) \ \text{Mod} \ m \]

以此得到 \(d_n\)

注意,需要开 __int128 或者手写高精度。开 long long 不够,会炸精度。而且必须用 signed 的。

posted @ 2026-02-07 17:34  L-Coding  阅读(0)  评论(0)    收藏  举报