目录
判断质数(试除法)
// 判断一个数是否为质数的函数
bool isPrime(int num) {
// 质数定义要求大于 1
if (num <= 1) {
return false;
}
// 从 2 开始到 num 的平方根进行试除
for (int i = 2; i * i <= num; ++i) {
if (num % i == 0) {
// 如果能被整除,说明不是质数
return false;
}
}
// 没有找到能整除它的数,是质数
return true;
}
质因数分解(质约数分解)
质因数分解是将一个正整数分解为若干个质数的乘积的过程。
// 质因数分解函数
std::vector<int> primeFactorization(int n) {
std::vector<int> factors;
// 从最小的质数 2 开始尝试
for (int i = 2; i * i <= n; ++i) {
while (n % i == 0) {
// 若能整除,i 是一个质因数,添加到结果中
factors.push_back(i);
// 除掉该质因数
n /= i;
}
}
// 如果 n 仍然大于 1,说明 n 本身是一个质数
if (n > 1) {
factors.push_back(n);
}
return factors;
}
素数筛
素数筛是用于高效找出一定范围内所有素数(质数)的算法。
埃式筛法
vector<int> sieveOfEratosthenes(int n) {
vector<bool> isPrime(n + 1, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i <= n; ++i) {
if (isPrime[i]) {//如果 i 是质数,我们需要标记它的所有倍数为非质数
for (int j = i * i; j <= n; j += i) {
isPrime[j] = false;
}
}
}
vector<int> primes;
for (int i = 2; i <= n; ++i) {
if (isPrime[i]) {
primes.push_back(i);
}
}
return primes;
}
求约数(求因数)
时间复杂度
// 函数用于找出一个数的所有约数
std::vector<int> findDivisors(int number) {
std::vector<int> divisors;
for (int i = 1; i <= number; ++i) {
if (number % i == 0) {
divisors.push_back(i);
}
}
return divisors;
}
求组合数
求C(a,b)
// 计算组合数的函数
long long combination(int n, int k) {
std::vector<std::vector<long long>> dp(n + 1, std::vector<long long>(k + 1, 0));
for (int i = 0; i <= n; ++i) {
dp[i][0] = 1;
if (i <= k) {
dp[i][i] = 1;
}
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= std::min(i, k); ++j) {
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
}
}
return dp[n][k];
}
求最大公约数 gcd算法
使用欧几里得算法(辗转相除法)
欧几里得算法的核心思想是:对于两个整数 a
和 b
(a > b
),它们的最大公约数等于 b
和 a % b
的最大公约数。
// 递归实现欧几里得算法
int gcd(int a, int b) {
if (b == 0) {
return a;
}
return gcd(b, a % b);
}
// 迭代实现欧几里得算法
int gcd_iterative(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
求最小公倍数 lcm算法
// 使用欧几里得算法计算最大公约数
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
// 计算最小公倍数
int lcm(int a, int b) {
return (a / gcd(a, b)) * b;
}
快速幂算法
用于快速计算a^n对m取模的结果。
// 快速幂函数,计算 base 的 exponent 次幂
long long fastPower(long long base, long long exponent) {
long long result = 1;
while (exponent > 0) {
if (exponent % 2 == 1) {
result *= base;
}
base *= base;
exponent /= 2;
}
return result;
}
扩展欧几里得算法
是在欧几里得算法(辗转相除法)的基础上进行扩展的算法。欧几里得算法用于计算两个整数的最大公约数,而扩展欧几里得算法不仅能计算出最大公约数,还能找到一对整数x和y,使得\(ax + by = gcd(a, b)\)成立
// 扩展欧几里得算法函数
// 返回 gcd(a, b),同时更新 x 和 y 使得 ax + by = gcd(a, b)
long long extendedGCD(long long a, long long b, long long &x, long long &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
long long x1, y1;
long long gcd = extendedGCD(b, a % b, x1, y1);
x = y1;
y = x1 - (a / b) * y1;
return gcd;
}
//结果说明
1.exgcd()的返回值是最大公约数
2.最后的(x,y)是方程ax + by = gcd(a,b)的解
3.如果exgcd()的结果是1(那么a和b互质,就存在逆元),那么x是a的逆元(x可能是负数,所以答案是getMod(x))