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\) 同阶.)