CF1285F Classical?

题意:给出数组 ,求 ,时限


特判 全同的情形。

显然 中相同的元素是无用的,可以先去个重。 考虑枚举 ,把所有 的倍数取出。

接下来,把他们都除以 ,问题转化成计算互质数对乘积的最大值。

从大到小枚举数,依次考虑 和比 大的集合 之间的贡献。

若发现有 使得 ,则贡献为

继续枚举时,只会枚举到 ,此时和某个满足 的可能的贡献为

所以,可以舍弃 所有 的数。


具体实现中,使用(从小到大的)单调栈,加入一个数 时,如果发现栈中存在某个数与 互质,则一路弹栈并计算贡献。

问题在于:如何判断栈中是否存在于 互质的元素。

我们需要一个数据结构,维护集合 ,支持加数,删数,查询是否有和 互质的数。这是经典问题。

维护 表示集合 的出现次数,则 中和 互质的数的个数是 维护 ,即 的倍数求和。加删数字时 ,相当于对 单点加减,即枚举 加减。

查询也是枚举因数。

单个问题复杂度为 ,问题总规模为

总复杂度为


改进:

对于任意 ,有 ,且

观察到 必然是 的因数,我们把每个数的所有因数加入,然后跑一遍互质的情况即可,复杂度为