快速幂
本文最后更新于:2024年2月12日 晚上
题目:
快速幂
快速幂
(二进制取幂,平方法),可以在$O(logN)$的时间复杂度内计算出$a^{n}$。
原理:n
有$\left \lfloor log_{2} \ n \right \rfloor + 1$个二进制位,所以只用计算$O(logn)$次乘法就可以计算出$a^{n}$。
以计算$3^{13}$为例:
$3^{13}=3^{(1101)_{2}}=3^{8}\cdot 3^{4}\cdot 3^{1}=3\cdot 81\cdot 6561$
$3^{1}=3$
$3^{2}=(3^{1})^{2}=3^{1}\cdot 3^{1}=9$
$3^{4}=(3^{2})^{2}=3^{2}\cdot 3^{2}=81$
$3^{8}=(3^{4})^{2}=3^{4}\cdot 3^{4}=6561$
static final int MOD = 998244353;
static long quick_pow(long a, long b) {
long ret = 1;
// if(b < 0){
// b = -b;
// a = 1 / a;
// }
while (b > 0) {
if ((b & 1) == 1) ret = ret * a % MOD;
a = a * a % MOD;
b >>= 1; // b /= 2;
}
return ret % MOD;
}
应用
求逆元
MOD
为质数,则i
的逆元就是$\frac{1}{i}=i^{mod-2}\% mod$
用快速幂求$i^{mod-2}$,算法时间复杂度为$O(logN)$
inv(i) = quick_pow(i, MOD-2) % MOD;
计算组合数
组合数计算公式:$C_{a}^{b} = \frac{a!}{(a - b)!\ b!}$
利用快速幂可以快速计算出$\frac{1}{(a-b)!}$和$\frac{1}{b!}$,从而快速计算出组合数。
时间复杂度:$O(NlogN)$
static final int MOD = 998244353;
static final int N = (int) 1e5 + 6;
static long[] fact = new long[N]; // 存储阶乘
static long[] inFact = new long[N]; // 存储阶乘逆元
// 快速幂 a^b
static long quick_pow(long a, long b) {
long ret = 1;
while (b > 0) {
if ((b & 1) == 1) ret = ret * a % MOD;
a = a * a % MOD;
b >>= 1; // b /= 2;
}
return ret % MOD;
}
// 计算组合数
static long comb(int a, int b) {
// 初始化
fact[0] = inFact[0] = 1;
for (int i = 1; i < N; i++) {
fact[i] = fact[i-1] * i % MOD;
inFact[i] = inFact[i-1] * quick_pow(i, MOD-2) % MOD;
}
return fact[a] * inFact[a - b] % MOD * inFact[b] % MOD;
}
本文作者: MerickBao
本文链接: https://merickbao.top/post/%E7%AE%97%E6%B3%95/%E6%95%B0%E5%AD%A6%E7%9F%A5%E8%AF%86/%E5%BF%AB%E9%80%9F%E5%B9%82.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!