Live2D

Solution -「NOI Simu.」记忆

\(\mathscr{Description}\)

  长度为 \(n\) 的序列 \(A\) 初始全 \(0\), \(C=0\). 第 \(i\ge0\) 个时刻对 \(A\) 进行如下变换:

  • \(\forall i\in[1,n],~a_i\gets a_i+i\).

  • \(\forall i\in[1,n]\land a_i>h_{i\bmod m},~a_i\gets h_{i\bmod m},C\gets C+1\).

给出 \(q\) 次询问, 每次给出 \(k\), 求出 \(C\)\(k\) 时刻后的值.

\(\mathscr{Solution}\)

  (嘴巴.)

  一个结论: 每次被赋值的数是 \(A\) 的一个后缀.

  另一个结论: 若 \(a_i\)\(t\) 时刻被赋值, 则一定在 \(t+m\) 时刻被再次赋值.

  由结论一, 先求出 \(a_1\) 第一次被赋值的位置. 设是 \(h_k\)\(t\) 时刻将它赋值. 那么, 其他所有数都会在 \(t\) 时刻被赋值. 对于 \(a_i\), 设其第一次被 \(h_k\) 赋值的时刻为 \(t'\), 那么其第一次被赋值的时刻 \(t''\) 应当有 \(t''\in[t'-m,t]\). 而因为 \(h_k\) 是已知的, 所以从 \(t'-m\)\(t\), 以此检查的 \(h\) 也是确定的. 而设 \(a_i\) 进入循环时值为 \(b\), 其被赋值需要满足 \(h_x<kx+b\), 若一个区间存在使得 \(h_x-kx-b<0\)\(x\), \(a_i\) 就会被其中的数赋值. 所以对下标建立线段树, 每个区间维护斜率单调栈, 即可 \(\mathcal O(n\log n)\) 线段树二分求出每个数第一次被赋值的时刻.

  对于询问, 我们需要求出若干完整周期的贡献和一段循环前缀的贡献. 前者比较好算. 对于后者, 二分得到被赋值至少一次的后缀 \([p,n]\), 将询问挂在 \(p\) 处. 从后往前扫描 \(a\), 每次 \(a\) 会失去一些赋值时刻, 建立关于时间的线段树维护历史和即可. 复杂度 \(\mathcal O(n\log n)\) (\(n,q\) 同阶.)

posted @ 2022-07-26 21:28  Rainybunny  阅读(88)  评论(0编辑  收藏  举报