zoukankan      html  css  js  c++  java
  • 算数基本定理与质因数分解

    目录

    目录地址

    上一篇

    下一篇

    算数基本定理

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

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

    证明

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

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

    其它情况下,因为 (n) 为合数,所以一定存在 (a,bin N)(1<aleq b<n) 使得 (n=a imes b)

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

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

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

    (ecause a<n)

    ( herefore m_aleq m)

    ( herefore a) 可唯一地写作 (displaystyle a=prod_{i=1}^{m_a}p_i^{ca_i}cdotprod_{i=m_a+1}^mp_i^0,p_iin Prime,c_iin N)

    我们令 (d_i=egin{cases} ca_i,0<ileq m_a \ \ 0,m_a<ileq m end{cases})

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

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

    因此 (n) 可唯一地写作 (displaystyle n=a imes b=prod_{i=1}^mp_i^{d_i}cdotprod_{i=1}^mp_i^{e_i}=prod_{i=1}^mp_i^{d_i+e_i},p_iin Prime,d_iin N,e_iin N)

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

    综上,算术基本定理得证


    质因数分解 (O(n))

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

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

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

    因此,将 (n) 划分为质数,即求出 (c_{1cdots 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) 以内的质数个数大概 ({nover ln n}) 个,每个质因数被除的内存循环,复杂度为 (o(log n))

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

    优化 (O(sqrt n))

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

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

    单这两个质因数的乘积 (p_a imes p_bleq sqrt n imes 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 nover ln{sqrt n}}={2sqrt noverln n}),每个质数的复杂度为 (o(log n))

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

    总复杂度 (O(sqrt n))

  • 相关阅读:
    Redis缓存穿透,缓存击穿,缓存雪崩
    Redis持久化机制
    Docker小白到实战之常用命令演示,通俗易懂
    分布式事务最终一致性-CAP框架轻松搞定
    gRPC四种模式、认证和授权实战演示,必赞~~~
    Docker小白到实战之开篇概述
    郑州 | 7月20日,想想都后怕
    避不开的分布式事务
    c++实现十大经典排序算法
    浏览器缓存机制总结
  • 原文地址:https://www.cnblogs.com/JustinRochester/p/12340602.html
Copyright © 2011-2022 走看看