快/光速冪學習筆記
快速冪:
前置知識:分治
快速冪是用來求解
$$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