【模板】快速幂
快速幂|二进制取幂--$ 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\)。
- 思路:
- 将 \(n\) 转化为二进制位, \(n=(n_tn_{t-1}...n_1n_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}\) 后,计算 \(\mathbf{\theta}(log n)\) 次乘法可计算出 \(a^n\)。
- 展开即为: \(n=n_tt^t+n_{t-1}t^{t-1}+n_{t-2}t^{t-2}+...+n_12^1+n_02^0\)
- 其中 \(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}\)
- 即计算了 \(\mathbf{\theta}(log n)\) 个 \(2^k\) 次幂的数,然后花费 \(\mathbf{\theta}(log n)\) 的时间选择二进制为1对应的幂来相乘。
实现:
标准快速幂:
- 递归:
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;
}