拓展欧拉定理 + 线段树.
拓展欧拉定理:当 $x>\varphi(P)$ 时,有 $a^x\equiv a^{x\bmod \varphi(P)+\varphi(P)} \pmod P$ .
那么只需要对每个位置维护出 $a\bmod P,a\bmod \varphi(P),a\bmod \varphi(\varphi(P)),\dots$ ,就可以实现单点修改.
每次把 $P$ 变成 $\varphi(P)$ ,最多变 $O(\log P)$ 次就会变成 $1$ ,所以每个位置只用维护 $k=O(\log P)$ 个值.
当一个数被操作了 $k$ 次后,就出现了 $\bmod 1$ 的情况,由于可以依次递推出每一项的值,所以再修改,它的值也不会变.
用线段树来实现修改操作,修改一个区间时,若区间内所有数都不变时,直接返回,否则继续向下暴力递归.
每个位置最多被修改 $O(\log P)$ 次,每次修改需要修改 $O(\log P)$ 个值,每修改一个值需要 $O(\log P)$ 算一次快速幂.
所有快速幂的底数都是 $c$ ,而指数不超过 $10^8$ ,所以可以对每种模数预处理出 $c^i,c^{i\times 10^4}$ 的值,快速幂就变成 $O(1)$ 了.
时间复杂度 $O(n\log^2 P)$ .
1 | //%std |