5.7——864E
864E
限时每日一题day31。由于课业繁忙,经过一个月的休整后重新回归了。现在感觉需要偶尔做一点2000+的题了,于是今天挑了一道2300分的题做一做。想了半天还是栽在了一个小地方而以失败告终。看完题解后觉得通过这道题又掌握与巩固了不少技巧,遂记录。
知识点:线性筛欧拉函数 + 线段树维护区间LCA + 区间并查集优化暴力
由于值域不是很大,因此可以采用线性筛来求1~5e6每个数的欧拉函数。并且通过打表发现每个数经 \(x = \phi(x)\) 变成 \(1\) 所需要的操作数不会超过 \(logW\) 次。因此可同时暴力预处理出1~5e6每个数变为1所需要的操作次数。
考虑题述的两种操作:一种是对区间 \(a[l, r]\) 的每个数进行一次 \(x = \phi(x)\) 的变换。如果直接无脑暴力修改每个位置,复杂度是 \(O(nm)\) 的。由上述可知对每个数的有效操作不会超过 \(logW\) 次,因此总共的有效操作数不会超过 \(nlogW\) 次。而 \(O(nm)\) 复杂度的根本原因就在于当某个数已经变为1时,这个数后续一定不会再含有效操作,但仍然会对这个数进行修改。考虑用区间并查集优化这个暴力:将所有当前已经变为1的位置和它的左侧位置合并,那么每次循环就可以从一个值非1的位置直接快速跳到下一个值非1的位置,使得总复杂度只与总共的有效修改次数相关。对于每轮修改,暴力点修线段树 和 直接修改 \(a[]\) 数组即可。
对于查询操作,首先要知道区间 \(a[l, r]\) 经过若干 \(x = \phi(x)\) 的变换后,最终变为哪一个数。显然 1 一定成立,但要想让操作次数最少,显然应当取最大值。那么怎么来算这个最大值呢?赛时纠结的就是这个地方,当时想的是钦定区间中某个数,然后用主席树暴力来看哪个数合法。但是由于操作1的存在,使得主席树需要带修,显然不是本蒟蒻会的东西。而赛时也想到了建图,但却没有再往深想。可以将1~5e6的每个数作为结点,添加 \(x -> \phi(x)\) 的边,显然这个图是一棵以1为根的有向树。那么在图中,区间 \(a[l,r]\) 的所有数可以变为的最大值就是它们的 \(LCA\),而每个数的操作次数就是它们到达这个 \(LCA\) 所需要的边数。由于 \(a\) 数组带修,可以用线段树来维护区间 \(LCA\)。
则该次查询答案即为:
其中 \(cnt[x]\) 表示将 \(x\) 通过 \(x -> \phi(x)\) 操作变为1,所需要的操作数。

浙公网安备 33010602011771号