算数基本定理(Fundamental Theorem of Arithmetic)即:任何一个大于1的正整数都能被唯一分解为有限个素数的乘积,可写作:
[math]\displaystyle{ N = \prod_{i=1}^n p_i^{c_i} = {p_1}^{c_1}{p_2}^{c_2}\cdots{p_n}^{c_n} }[/math]
其中 [math]\displaystyle{ c_i }[/math] 都是正整数,[math]\displaystyle{ p_i }[/math] 都是素数,且满足 [math]\displaystyle{ p_1\lt p_2\lt \cdots \lt p_n }[/math]
实现
结合素数判定的“试除法”和素数筛选的“Eratosthenes筛法”,我们可以扫描 [math]\displaystyle{ 2 \backsim \lfloor \sqrt N \rfloor }[/math] 的每个数d,若d能整除N,则从N中除掉所有的因子d,同时累计除去的d的个数。
因为一个合数的因子一定在扫描到这个合数之前就从N中被除掉了,所以在上市u过程中能整除N的一定是素数。最终就得到了分解素因数的结果,易知时间复杂度为 [math]\displaystyle{ O(\sqrt N) }[/math]。
特别的,若N没有被任何 [math]\displaystyle{ 2 \backsim \lfloor \sqrt N \rfloor }[/math] 的数整除,则N是素数,无需分解。
int c[MAX_N], p[MAX_N];
int m;
void divide(int n) {
m = 0;
for (int i = 2; i < sqrt(n); ++i) {
if (n % i == 0) {
p[++m] = i;
c[m] = 0;
}
while (n % i == 0) {
n /= i;
c[m]++;
}
}
if (n > 1) {
p[++m] = n;
c[m] = 1;
}
}
参考资料
- 算法竞赛进阶指南,李煜东,137页