算数基本定理与质因数分解

目录

目录地址

上一篇

下一篇

算数基本定理

算术基本定理可以表述为:对任意大于 \(1\) 的自然数,若不为质数,则一定能且只能写成一种有限个质数乘积的形式

或者可以表述为:对 \(\forall n\in N\)\(n>1\) ,对所有的 \(m\) 个小于等于 \(n\) 质数 \(p_{1\cdots m}\)\(\displaystyle n=\prod_{i=1}^mp_i^{c_i},p_i\in Prime,c_i\in N\) 存在且唯一存在

证明

我们用归纳法证明:考虑合数 \(n\) ,假设 \(n\) 以内的数要么都是质数,要么所有合数都符合上述定理

\(n\) 为最小的合数 \(4\) 时,\(n=2\times 2=2^2\) 符合上述定理

其它情况下,因为 \(n\) 为合数,所以一定存在 \(a,b\in N\)\(1<a\leq b<n\) 使得 \(n=a\times b\)

设一共有 \(m\) 个小于等于 \(n\) 的质数 \(p_{1\cdots m}\)

由于 \(a<n\) 因此 \(a\) 符合上述定理

\(a\) 可唯一地写作 \(\displaystyle a=\prod_{i=1}^{m_a}p_i^{ca_i},p_i\in Prime,c_i\in N\)

\(\because a<n\)

\(\therefore m_a\leq m\)

\(\therefore a\) 可唯一地写作 \(\displaystyle a=\prod_{i=1}^{m_a}p_i^{ca_i}\cdot\prod_{i=m_a+1}^mp_i^0,p_i\in Prime,c_i\in N\)

我们令 \(d_i=\begin{cases} ca_i,0<i\leq m_a \\\ \\ 0,m_a<i\leq m \end{cases}\)

\(a\) 可唯一地写作 \(\displaystyle a=\prod_{i=1}^mp_i^{d_i},p_i\in Prime,d_i\in N\)

同理,我们可以将 \(b\) 唯一地写作 \(\displaystyle b=\prod_{i=1}^mp_i^{e_i},p_i\in Prime,e_i\in N\)

因此 \(n\) 可唯一地写作 \(\displaystyle n=a\times b=\prod_{i=1}^mp_i^{d_i}\cdot\prod_{i=1}^mp_i^{e_i}=\prod_{i=1}^mp_i^{d_i+e_i},p_i\in Prime,d_i\in N,e_i\in N\)

\(c_i=d_i+e_i\) 因此,证得上述结论

综上,算术基本定理得证


质因数分解 \(O(n)\)

由算数基本定理,我们得到,一个大于 \(1\) 的自然数,一定能分解为若干个质数的乘积

下面我们来具体考虑如何划分:

首先,定理的成立表明:对 \(n\) 以内的 \(m\) 个质数 \(p_{1\cdots m}\) ,保证 \(n=\prod_{i=1}^mp_i^{c_i},p_i\in Prime,c_i\in N\) 这一等式中的 \(c_i\) 都是唯一确定的

因此,将 \(n\) 划分为质数,即求出 \(c_{1\cdots m}\)

首先,十分显然:我们可以花费 \(O(n)\) 的时间筛出 \(n\) 以内的质数,然后一个一个去实验

int prime[MAXN],cntprime=0,c[MAXN]={0};
sieve_prime(int n){
    ...
}
...
sieve_prime(n);
int copy=n;
for(int i=1;i<=cntprime;i++){
    if(copy%prime[i]!=0) continue;
    while(copy%prime[i]==0){
        copy/=prime[i];
        c[i]++;
    }
}

\(n\) 以内的质数个数大概 \({n\over \ln n}\) 个,每个质因数被除的内存循环,复杂度为 \(o(\log n)\)

因此,分解的复杂度为 \(o(n)\) ,加上前面筛素数,总复杂度 \(O(n)\)

优化 \(O(\sqrt n)\)

通过细心观察可以发现:对于大于等于 \(\sqrt n\) 的质因数,一定不会存在超过一个

若存在两个大于等于 \(\sqrt n\) 的质因数,设它们分别为 \(p_a,p_b,p_a\leq p_b\)

单这两个质因数的乘积 \(p_a\times p_b\leq \sqrt n\times \sqrt n=n\) 就注定了不可能同时是 \(n\) 的因数

因此大于等于 \(\sqrt n\) 的质因数,一定不会存在超过一个

所以我们只需要花费 \(O(\sqrt n)\)\(\sqrt n\) 以内的质数筛出来,然后重复上述操作

最后得到的如果是 \(1\) ,则代表没有大于 \(\sqrt n\) 的质因数;否则,剩下的本身就是质因数

int prime[MAXN],cntprime=0,c[MAXN]={0};
sieve_prime(int n){
    ...
}
...
sieve_prime( (int)sqrt(n) );//或者在函数里面改为 i*i<=n
int copy=n;
for(int i=1;i<=cntprime;i++){
    if(copy%prime[i]!=0) continue;
    while(copy%prime[i]==0){
        copy/=prime[i];
        c[i]++;
    }
}
if(copy!=1){
    prime[++cntprime]=copy;
    c[cntprime]++;
}

因为 \(\sqrt n\) 以内的质数个数大概 \({\sqrt n\over \ln{\sqrt n}}={2\sqrt n\over\ln n}\),每个质数的复杂度为 \(o(\log n)\)

因此分解的复杂度为 \(o(\sqrt n)\) ,加上筛质数的复杂度

总复杂度 \(O(\sqrt n)\)

posted @ 2020-02-21 11:04  JustinRochester  阅读(803)  评论(0编辑  收藏  举报