数学
最大公约数 最小公倍数 唯一分解定理
// 1. 最大公约数(GCD)- 欧几里得算法(迭代版)
long long gcd(long long a, long long b) {
while (b != 0) {
long long temp = b;
b = a % b;
a = temp;
}
return a;
}
// 2. 最小公倍数(LCM)- 基于GCD计算
long long lcm(long long a, long long b) {
if (a == 0 || b == 0) return 0; // 0和任何数的最小公倍数是0
return (a / gcd(a, b)) * b; // 先除后乘避免溢出
}
分解质因数 判定素数 素数筛
分解质因数
vector<int> primeFactorization(int n) {
vector<int> factors;
for (int i = 2; i * i <= n; i++) {
while (n % i == 0) {
factors.push_back(i);
n /= i;
}
}
if (n > 1) factors.push_back(n);
return factors;
}
素数筛:使用素数的倍数去筛掉合数
但是一个合数会被多次素数筛除影响效率
bool isnp[MAXN]; // is not prime: 不是素数
void init(int n)
{
for (int i = 2; i * i <= n; i++)
if (!isnp[i])
for (int j = i * i; j <= n; j += i)
isnp[j] = 1;
}
引入欧拉筛:不会重复筛除
合数只筛一次 保证是被最小质因数筛除
质数就需要遍历全部筛除
bool isnp[MAXN];
vector<int> primes; // 质数表
void init(int n)
{
for (int i = 2; i <= n; i++)
{
if (!isnp[i])
primes.push_back(i);
for (int p : primes)
{
//越界退出 使用乘法快于除法
if (p * i > n)
break;
isnp[p * i] = 1;
//合数只筛一次 保证是被最小质因数筛除
if (i % p == 0)
break;
}
}
}
快速幂 费马小定理逆元
非递归快速幂
long long quickpow(long long a,long long n)
{
long long res=1;
while(n>0)
{
if(n&1) res*=a;//如果指数当前二进制位数字为1,则乘上这个
a=a*a;//待乘指数向前一位
n>>=1;//指数当前位数向前一位
}
return res;
}