快/光速幂学习笔记

快速幂:

前置知识:分治

快速幂是用来求解

$$a^b$$

的一种基于分治的算法。

首先根据我们学过的同底数幂乘法,显然有

$$a^b=a^{\frac{b}{2}}\times a^{\frac{b}{2}}$$

但是$\frac{b}{2}$有可能是小数啊QAQ,这样的话不就更麻烦了吗?

考虑分类讨论:

当$b$为偶数时,这样的话$\frac{b}{2}$为整数,故此时:

$$a^b=a^{\frac{b}{2}}\times a^{\frac{b}{2}}$$

当$b$为奇数时,这样的话可以将$\frac{b}{2}$看作$\lfloor\frac{b}{2}\rfloor$,但是我们发现这样的话最终的指数位置会少一个$1$,所以最终答案我们多乘上一个$a$就行了:

$$a^b=a^{\lfloor\frac{b}{2}\rfloor}\times a^{\lfloor\frac{b}{2}\rfloor}\times a$$

然后这就是快速幂的基本原理啦,是不是非常简单呢(((

接下来我们可以写出递归版代码:

ll ksm(ll b,ll p){
	if(!p) return 1;
        if(p==1) return b%mod;
	ll t=ksm(b,p/2)%mod;
	if(n&1) return b*t*t%mod;
	else return t*t%mod;
}

 但是递归不够快速啊,所以快速幂自然还有非递归的啦:

ll ksm(ll b,ll p){
	ll ans=1,base=b;
	while(p){
		if(p&1){
			ans*=base;
			ans%=k;
		}
		base*=base;
		base%=k;
		p/=2;
	}
	return ans;
} 

 应该也很好理解吧(雾

时间复杂度$O(\log p)$

光速幂:

大概无前置知识?

光速幂适用于底数固定,模数固定的情况。

时间复杂度是$O(\sqrt{b})$($b$为指数)预处理,$O(1)$查询,适用范围并不广

其核心思想是设一个阈值$\omega$,预处理出$a^1,a^2,a^3...a^{\omega-1}$以及$a^{\omega},a^{2\times\omega},a^{3\times\omega}...a^{\lfloor\frac{b}{\omega}\rfloor\times\omega}$

那么$a^b$便可以转化为$a^{b\pmod\omega}\times a^{\lfloor\frac{b}{\omega}\rfloor\times\omega}$

根据均值不等式易证$\omega=\sqrt{b}$时时间复杂度最优

所以我们就得到了$O(\sqrt{b})$预处理,$O(1)$查询的光速幂/cy

上一篇:Educational Codeforces Round 99 (Rated for Div. 2) A-F题解


下一篇:题解 T121450 [Cnoi2020]明天后的幻想乡