C++快速幂与大数取模算法示例
本文主要介绍C++中实现快速幂算法和大数取模算法的示例以及相关代码。快速幂算法可以很好地解决指数较大的幂运算问题,大数取模算法则可以在计算过程中避免数值过大而发生的溢出错误。
快速幂算法原理
快速幂算法是指通过对指数进行二进制分解后,根据分解结果按照乘幂的顺序计算幂运算结果。其本质上是一种分治策略,可以大大减少指数较大情况下的计算次数。
举例来说,如果要计算$x^y$,其中$y$的二进制表示为$b_k2^k+b_{k-1}2^{k-1}+...+b_12^1+b_02^0$,则可以按照如下方式进行计算:
- 初始化计算结果$res=1$;
- 从高位到低位依次遍历二进制表示,当遍历到$b_k$时进行如下操作:
- $res \leftarrow res \times res$;
- 如果$b_k=1$,则进行$res \leftarrow res \times x$的操作;
- 遍历结束,返回计算结果$res$。
通过上述方法,可以将计算指数为$y$的幂的时间复杂度降低至$O(log_2 y)$级别。
大数取模算法原理
大数取模算法是指通过一定的数学方法,在运算过程中不直接对大数进行运算,而是不断对大数取模得到小数后再进行运算,并最终取模得到最终结果。其本质原理是利用取模运算对数值的抑制作用,可以避免浮点数以及整数过大而引发的误差。
常用的大数取模算法有如下两种:
- Barrett约减算法。其基本思想是对大数进行规约,使其取模结果不超过另一个已知较小的数$m$,从而避免数值过大带来的误差。Barrett约减算法的时间复杂度为$O(n^2)$,其中$n$为大数的长度。
- 快速取模算法。快速取模算法则是一种基于快速幂算法的取模算法,可以快速地对大数进行取模,从而避免数值过大带来的误差。快速取模算法的时间复杂度为$O(nlog_2 n)$。
C++示例
下面给出C++中实现快速幂算法和大数取模算法的示例代码。
快速幂算法示例
以下示例展示了如何使用C++实现快速幂算法:
long long qmi(long long a, int b) {
long long res = 1;
while (b) {
if (b & 1) res *= a;
a *= a;
b >>= 1;
}
return res;
}
上述代码通过右移运算符和按位与运算符来实现二进制位的判断和移动,从而实现了快速幂算法的计算。
快速幂取模示例
以下示例展示了如何使用快速幂算法进行大数取模:
long long qmi_mod(long long a, int b, int p) {
long long res = 1;
while (b) {
if (b & 1) res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}
上述代码实现了快速幂算法与取模运算的结合,其中$p$为取模的模数。
Barrett约减示例
以下示例展示了如何使用C++实现Barrett约减算法:
struct Barrett {
int m;
int k; // 2k >= ceil(logb(m))
long long r0; // 运算中的临时变量
Barrett(int _m) : m(_m) {
k = ceil(log2(m));
r0 = qmi(10, 2 * k) / m + 1;
}
int reduce(long long x) { // 将x规约至[0, m)
long long q = ((long long)r0 * x) >> 2 * k;
long long r = x - q * m;
return r < m ? r : r - m;
}
};
上述代码利用了C++中的结构体和重载运算符的特性,通过C++的内置计算函数ceil
、log2
和qmi
来实现Barrett约减算法的计算。
快速取模示例
以下示例展示了如何使用快速幂算法进行快速取模:
long long qmi_mod_2(long long a, int b, int p) {
long long res = 1;
while (b) {
if (b & 1) res = (res * a) % p;
a = (a * a) % p;
b >>= 1;
}
return res;
}
int fast_mod(int a, int b, int p) {
return qmi_mod_2(a, b % (p - 1), p);
}
上述代码通过对指数取模,从而将幂次数降低至$p-1$以内,利用快速幂算法进行计算,并最终再次对结果进行取模以得到最终结果。
以上就是对C++快速幂与大数取模算法示例的详细讲解。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++快速幂与大数取模算法示例 - Python技术站