题意
定义函数 $f(x)=c^x$
维护给定序列 $a_i$,支持两种操作(p,c 由输入给定):
-
将数列第 l 到 r 项中的每一项 $a_i$,赋值为 $f(a_i)$
-
查询 $\sum_{i=l}^{i\leq r}a_i\ \pmod p$
分析
计算方法
首先考虑一项如何计算,由扩展欧拉定理(详见 OI-wiki)
$$ a^b\equiv \begin{cases} a^{b\bmod\varphi(p)},\,&\gcd(a,\,p)=1\\ a^b,&\gcd(a,\,p)\ne1,\,b<\varphi(p)\\ a^{b\bmod\varphi(p)+\varphi(p)},&\gcd(a,\,p)\ne1,\,b\ge\varphi(p) \end{cases} \pmod p $$可以转化问题为:
$$ \begin{aligned} &f^x(a_i) \pmod p\\ =&\begin{cases} f(f^{x-1}(a_i))&(f^{x-1}(a_i)<\varphi(p))\\ f(f^{x-1}(a_i)\bmod \varphi(p)+\varphi(p))&(f^{x-1}(a_i)\ge\varphi(p)) \end{cases} \end{aligned} $$以此类推,就能递归求解答案,不妨设 $\varphi ^t (p)=1$ 当且仅当 $t\ge z$,则递归的边界为:
$$ \begin{cases} a_i &\pmod {\varphi^{z-x}(p)}&(x关于 z 大小的证明:
- p 为偶数时,$\varphi(p)\leq \frac p 2$
- p为奇数时,$\varphi(p)$ 为偶数
计算次数
通过刚才的计算方法,我们发现:若 $x\ge z$,则函数在边界处的返回值为 0,接下来整个计算过程都与 x 无关。也即:每个元素 $a_i$ 在操作了 z 次之后,其值就不再变化!
所以,我们可以用一个线段树来维护区间和,以及区间内操作次数最少的元素操作了多少次,修改时,如果区间内的最少操作次数小于 z,那么就暴力计算之,并更新线段树。这样就能实现一个 $O(n\log^3 p )$ 的做法,得到 90 分的好成绩。
小优化
考虑如何优化前文所述的快速幂,因为底数 c 是已知的,而指数小于等于 p,于是我们可预处理出 $c^i\ (i\in[1, \sqrt p] )$ 以及 $c^{i \times \sqrt p}\ (i\in[1, \sqrt p])$,每次求快速幂直接把 $c^{i\ \bmod \sqrt p}$ 与 $c^{\lfloor\frac i {\sqrt p }\rfloor\times \sqrt p}$ 拼接即可。
代码
(还挺快的)
|
|
实现细节
-
代码中,我用
phip[i]
预处理出了 $\varphi^i(p)$ 的值,其中phic+1
则对应前文中 $z$ 的定义。 -
我还定义了一个函数
eulermod(x,y)
,表示以欧拉定理中的形式处理 x 模 y 的结果,这样我们就可以在计算欧拉函数的过程中免于讨论的烦恼。
|
|
-
可能有人会问:在计算 $f^x(a_i)\ (\operatorname{eulermod}\ p)$ 时,会不会出现本来 $f^x(a_i)$ 是大于等于 p 的, 但是由于计算 $f^{x-1}(a_i)$ 函数返回的结果是 $\operatorname{eulermod}\ \varphi(p)$ 意义下的,从而导致算出来的 $f((f^{x-1}(a_i)\ (\operatorname{eulermod}\ p)) < p$?
-
答案是否定的,证明如下:
- 若 $c=0/1$,显然 $f^x(a_i)
- 若 $c\ge 2$:
- 如果 $f^{x-1}(a_i)< \varphi(p)$:则 $f^{x-1}(a_i)=f^{x-1}(a_i)\ (\operatorname{eulermod}\ \varphi (p))$ 没有上述问题
- 如果 $f^{x-1}(a_i)\ge \varphi(p)$:则因为 $\log_2p \le \varphi(p)$,所以 $p \le f(\varphi (p)) \le f((f^{x-1}(a_i)\ (\operatorname{eulermod}\ p))$,上述问题同样不存在,证毕。
- 若 $c=0/1$,显然 $f^x(a_i)