【模板】快速冪
阿新 • • 發佈:2020-11-03
快速冪|二進位制取冪--$ Binary Exponentiation $
描述:
- 應用定理: \(a^b+c=a^b+a^c,a^2b=a^b \cdot a^b=(a^b)^2\)。
- 時間複雜度: \(\mathbf{\theta}(log n)\) 時間內算出 \(a^n\)。
- 思路:
0.1將 \(n\) 轉化為二進位制位, \(n=(n_tn_{t-1}...n_1n_0)_2\)。
0.2 \(n\) 有 \(\left\lfloor\log_2 n \right\rfloor\) 個進位制位,所以我們算出 \(a^1,a^2,a^4,a^8,...,a^{2^\left\lfloor\log_2 n \right\rfloor}\)
0.3展開即為: $$n=n_tt^t+n_{t-1}t^{t-1}+n_{t-2}t^{t-2}+...+n_12^1+n_02^0$$
0.4其中 \(n_i\in\{0,1\}\) 那麼就有 $$a^n=(a^{n_t2^t+...+n_02^0})=a^{n_0 2^0}\times a^{n_1 2^1}\times ...\times a^{n_t 2^t}$$
0.5即計算了 \(\mathbf{\theta}(log n)\) 個 \(2^k\) 次冪的數,然後花費 \(\mathbf{\theta}(log n)\)
實現:
標準快速冪:
- 遞迴:
long long int binpow(long long int a,long long int b)
{
if(b==0)return 1;
long long int res=binpow(a,b/2);
return b%2?res*res*a:res*res;
}
- 遞推:
long long int binpow(long long int a,long long int b) { long long int res=1; while(b>0) { if(b&1)res=res*a; a=a*a,b>>=1; } return res; }
取模快速冪:
long long int binpow_mod(long long int a,long long int b,long long int m)
{
a%=m;
long long int res=1%m;
while(b>0)
{
if(b&1)res=res*a%m;
a=a*a%m;
b>>=1;
}
return res;
}