【2 月小记】Part 1: LCOI-R1 比赛总结
LCOI-R1 比赛总结
T1
考点
数学、推式子
题意
给你有一个数 \(cur\),初始 \(cur = s\)。
定义一次操作为
求 \(n\) 次操作后 \(cur\) 的值。
要求 \(O(1)\) 时间复杂度内计算。
简析
注意到因为 \(cur\) 的变化仅与它和 \(t\) 之间的相对位置关系有关,所以我们不妨把 \(s\) 和 \(t\) 平移一下。
定义差值
于是操作变为
如今问题转化为:已知 \(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]\) 后,操作规则为
记这个区间的长度为 \(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\) 调整到原来的循环区间内。也就是说,我们通过一步转化,使操作变为了
进一步地,当我们有 \(i\) 次操作的时候,情况又会变为什么样?
考虑计算累积位移,不考虑循环区间边界的限制,我们有
然后,将累计位移取模到一个周期内,记
最后调整到循环区间内,有
记上面这种对 \(d\) 的特殊运算为 \(\text{Mod}\),那么有
以此得到 \(d_n\)。
注意,需要开 __int128 或者手写高精度。开 long long 不够,会炸精度。而且必须用 signed 的。

浙公网安备 33010602011771号