WZU ACM集训队10.25训练D题补
题目大意
定义函数 $f(n)$ 为:
特别地 $0^0=1$
求对于 $n\in[2,1e9]$ 的 $f(n)\mod m$
思路
对于题目的函数 $f(n)$,我们假设一个多位十进制数 那么对于该函数可以递归成以下形式:
即求 $(*)$ 式的结果。
首先我们马上会想到用快速幂和记忆化存储 f(n)的值,但是这样递归很容易溢出,即使大数模拟也会超时,我们下面考虑如何用数论化简。
欧拉定理
欧拉定理指出,对于整数 $m\gt0$ 和整数 $a$ ,且 $\mathbf{gcd}(a,m)=1$ ,有:
下面我们给出该定理的应用,考虑这个数 $a^b\mod m$
这里同时两边乘上 $a^k$,然后把 $b$ 分解为 $b=q\cdot \varphi(m)+b\mod \varphi(m)$ 带入这个数有:
即有欧拉降幂公式:
$$ a^b\equiv a^{b\mod{\varphi(m)}} \pmod m \tag{\#} $$这样当 $\mathbf{gcd}(a,m)=1$ 的大数幂模 $a^b \mod m$ 就可以写成 $a^{b\mod \varphi (m)}\mod m$ 来降幂,即利用了模数的周期性质
举个例子:
求 $3^{10000000}\mod 1000$,由于 $\mathbf{gcd}(3,1000)=1$,那么我们使用使用(#)式化简有幂为:
于是答案为 $3^{0}\mod 1000=1$,这里不信可以自己用 python 按一下
求 $3^{4^5} \mod 10$ ,我们可以逐层进行降幂,先算 $4^5=1024$,这里 $\mathbf{gcd}(3,100)=1$ 那么我们使用(#)式化简有幂为: $1004\mod \varphi(100)= 1024\mod 40=24$,于是只要计算 $3^{24}\mod 10$ 即可
扩展欧拉定理
上面的欧拉定理(*)式要求底数和指数互素,这里给出进一步的推广至一般情况;
有了以上公式,我们可以将快速幂在 $O(\log \varphi(m))$ 下计算
具体做法
对于该函数化为指数幂的形式后,从上向下不断运用欧拉定理以及快速幂,即可:
- 不断计算上层指数 $f(n/10)\mod \varphi (m)$ 的值,同时判断其是否大于等于 $\varphi (m)$
- 像之前那个例子一样构造指数:
- 如果其 $\ge \varphi (m)$ 且不互质,则该指数 $+\varphi(m)$
- 如果其 $<\varphi(m)$ 且不互质,则直接将 b 作为指数
- 如果其互质,则指数为 $b\mod \varphi(m)$
- 构造完指数后使用快速幂进行计算
记得剪枝,
- 对于 $a=0$ 时,如果 $b≠0$,那么直接
return 0,反之return 1 对于 $a=1$ 时,直接
return 1这样,该题整体的时间复杂度可以降至 $O(\log{10}n\cdot\sqrt m + log{10}n\cdot\log m)$
代码
1 |
|




