因数
若无特殊说明,本章涉及的变量皆为正整数.
定义 #
若 $n \div d$ 为整数,则 $d$ 是 $n$ 的因数,记作 $d\mid n$.
算数基本定理 #
任意正整数 $n$ 都能唯一地分解为有限个质数的乘积.
$$n=p_1^{\normalsize c_1}\cdot p_2^{\normalsize c_2}\cdots p_m^{\normalsize c_m}$$
分解质因数 #
试除法 #
将 $n$ 分解成 算数基本定理 的形式. 如 $$360=2^3\times 3^2\times 5$$
枚举 $i=2,3,\cdots,\sqrt{n}$,除尽 $n$ 中的 $i$,并记录除的次数.
const int N = 1e6;
vector<int> P, C;
void factor(int n) {
for (int i = 2; i <= sqrt(n); i ++) {
if (n % i == 0) {
P.push_back(i), C.push_back(1);
while (n % i == 0)
n /= i, C.back() ++;
}
}
if (n != 1) {
P.push_back(n);
C.push_back(1);
}
}
倍数法 #
求 $[1,n]$ 中各整数的因数集 $fact$. 如
$$fact[12]=\{1,2,3,4,6,12\}$$
对各整数依次进行 试除法 效率差,此时考虑倍数法:
$i$ 的倍数必有因数 $i$.
枚举 $i=1,2,\cdots,n$,并在 $i$ 的倍数的因数集中加入 $i$.
时间复杂度为 $O(n\log{n})$.
const int N = 1e6;
vector<int> fact[N];
void factor(int n) {
for (int i = 1; i <= n; i ++) {
for (int j = 1; i * j <= n; j ++) {
fact[i * j].push_back(i);
}
}
}