2025.4.8 CWOI 模拟赛T1-T2

T1 序列加法机

做过异或粽子的可能对这个 Trick 比较熟悉。

首先,我们设 \(f(x,k)\) 表示把 \(x\) 分为 \(k\) 个数的和的平方和的最小值。

容易发现,对于每一个 \(x\)\(f(x,k)\) 一定单调递减。这个还可以 \(\Omicron(1)\) 计算,就是先均摊,多的再平均分,$ f(x,k) = (x \bmod k)(\lfloor \frac{x}{k} \rfloor + 1) ^ 2 + (k - x \bmod k)(\lfloor \frac{x}{k} \rfloor) ^ 2 $。

于是,我们就可以用一个堆,把所有值塞进去,每次取堆顶,计算完贡献之后塞回去,这样跑 \(m - cnt\) 次,因为你要对 \(cnt\) 个非 \(0\) 元素进行一次操作。

T2 摸鱼军训

首先,我们预处理 \(rev _ x\) 表示在 \(x\) 前面且 \(\gt x\) 的数的个数,其中这个 \(x\) 表示一个值。

我们发现,对于第 \(k\) 次操作后:

  • \(rev _ {a _ i} \ge k\),则位置会变成 \(i - k\),下面称为保留的元素
  • 否则,我们需要先不考虑保留的元素,然后在剩下的位置按照递增顺序把不保留的元素填进去

求解 \(rev _ x \ge k\) 的是很简单的,不考虑,着重考虑 \(rev _ x \lt k\) 的。

我们需要知道这个值在所有 \(rev \lt k\) 的值中是第几个,记为 \(rank\),然后,我们还需要找到第 \(rank\) 个空的位置。

求出 \(rev\) 和查询排名可以写两个树状数组来解决,求空的位置可以这么做:

我们建一棵线段树,大小为 \(\textbf{2n}\)\(0\) 表示这里不是空,\(1\) 相反。对于所有 \(x \le n\),初始化为 \(0\),否则设为 \(1\)

记录每个 \(x\) 对应的 \(pos _ x\),处理这个值的时候,把 \(T _ {pos _ x}\) 设为 \(1\)。这个时间刻的所有操作执行完了,把 \(T _ k\) 设置为 \(0\),因为前 \(k\) 个已经被移走了。

然后对于一个 \(rev \lt k\) 的询问,在线段树上二分得到第 \(rank\)\(1\) 的位置,减去 \(k\) 就是答案。

第一版代码我还极其糖的写了个二分套平衡树

posted @ 2025-04-08 21:03  xguagua_233  阅读(18)  评论(0)    收藏  举报