CF2148G 题解

太困了,所有数据结构都忘光了,所以这个做法没什么数据结构。

首先我们发现,假如 ,考虑将 重排后的数组 满足 。显然,一个序列的 是非单调递减的,因此整个序列的 在第 项之后就没有变过。考虑将所有数除掉整个序列的 ,这样前 项的 就非 而后面的就全是

显然我们可以考虑枚举前 项的 ,如果有 个数整除这个 ,那我们就把这 个数放前面,答案至少为 。因此考虑维护一个数组 ,表示当前数组中整除 的数的个数。然后我们只需要枚举这个 ,求将答案对整除这个数的数的个数取 即可。由于我们之前除掉了一个 ,这里直接乘回来(那除掉是不是有点多余)。

此时我们得到了一个算法:

  • 加入一个新的数时,枚举所有因数,将 的对应位置加一。
  • 求出当前的 ,枚举倍数求出答案。

这个做法是 的。考虑一个序列的 的情况就能卡满。

我们又注意到,假如加入一个数之后 没有变化,那么 倍数的位置没有变。而这个时候只有 个位置有变化,因此对变化的位置中满足条件的取 即可。假如变化了之后,我们再重新枚举。注意到 变化之后显然是原来的因数,大小至少除以 ,因此最多只会枚举 遍。

这样总复杂度就到了

此外还有一个小优化。在枚举倍数的时候,我们并不关心这个 具体是什么,我们只关心是否存在这样一组的解。因此我们可以考虑只枚举当前 的质数倍即可。

代码在这里


CF2148G 题解
https://blogs.sving1024.top/posts/15515/
发布于
2025年9月14日
许可协议