快速幂是在a,ba,ba,b很大时快速求出aba^bab的一种方法。那怎么用快速幂求aba^bab呢?
我们可以采用二分的思想。首先,要求aba^bab,我们可以先求a⌊b/2⌋a^{\lfloor b/2\rfloor}a⌊b/2⌋,设这个值为ppp,则
- 如果bbb为奇数,则ab=p∗p∗aa^b=p*p*aab=p∗p∗a
- 如果bbb为偶数,则ab=p∗pa^b=p*pab=p∗p
也就是说,我们要求a⌊b/2⌋a^{\lfloor b/2\rfloor}a⌊b/2⌋
于是,根据这个思想,我们可以设函数mi(a,b)mi(a,b)mi(a,b)表示aaa的bbb次方,则可以推出式子:
mi(a,b)={mi(a,b−12)×mi(a,b−12)×a,b为奇数mi(a,b2)×mi(a,b2),b为偶数且b≠01, b=0mi(a,b)=\left\{\begin{matrix}mi(a,\frac{b-1}{2})\times mi(a,\frac{b-1}{2})\times a,\qquad\qquad b为奇数 \\ mi(a,\frac{b}{2})\times mi(a,\frac{b}{2}),\qquad\qquad b为偶数且b\neq 0\\1,\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad \ b=0\end{matrix}\right.mi(a,b)=⎩⎨⎧mi(a,2b−1)×mi(a,2b−1)×a,b为奇数mi(a,2b)×mi(a,2b),b为偶数且b=01, b=0
于是,我们就可以用O(logb)O(logb)O(logb)的时间复杂度求出aba^bab的值了。
long long mi(long long a,long long b){
if(b==0) return 1;
long long re=mi(a,b/2);
re=re*re%mod;
if(b%2) re=re*a%mod;
return re;
}