1. 程式人生 > 實用技巧 >快/光速冪學習筆記

快/光速冪學習筆記

快速冪:

前置知識:分治

快速冪是用來求解

$$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