zoukankan      html  css  js  c++  java
  • 质数

    质数的定义

    质数又称作素数.
    质数是除了1和本身没有其他因数的数.
    与之相反的是合数.
    1不属于质数或合数.

    质数的判断

    假设我们要判断(n)是不是质数.
    从2枚举(n-1),若能整除(n),(n)就不是质数.
    时间复杂度(O(n)).
    但因数是成对的(除了(sqrt n))
    (n=c_1 c_2),假设(c_1 le c_2)
    (c_1 le sqrt n , c_2 ge sqrt n)
    所以只需枚举到(sqrt n).

    bool isprime(long long x) {
        for(int i=2; i<=sqrt(x); i++) {
            if(x%i==0) return false;
        }
        return true;
    }
    

    时间复杂度(O(sqrt n)).

    质数筛法

    现在我们要求(1)(n)中全部质数.

    暴力

    最简单的办法就是判断每个数是否为质数.
    时间复杂度(O(n sqrt n)).

    埃氏筛法

    (1)(sqrt n),若这个数没有被标记,即为质数.
    只要发现了一个质数(t),就把从(1)(n)中全部(t)的倍数标记.
    时间复杂度(O(n log n))

    欧拉线性筛法

    对于每个(i(1<i<n)),筛去所有小于(i)的质数与(i)的乘积.
    不难发现,有些合数被重复筛去.
    设所有小于(i)的质数分别为(p_1,p_2,...,p_j).
    (i\%p_k=0)时,停止筛(i)的倍数,即可避免重复.
    因为当(l>k)时,所有(i*p_l)都会被比(i)大的数与(p_k)的乘积筛去.

    for(int i=2;i<=n;i++){
        if(!vis[i]) {
            cnt++;
            pri[cnt]=i;
        }
        for(int j=1;i*pri[j]<=n;j++){
            vis[i*pri[j]]=true;
            if(i%pri[j]==0) break;
        }
    }
    

    时间复杂度(O(n))

    质因数分解

    一个数的质因数必定小于等于(sqrt n).
    只需把(i)(2)枚举到(sqrt n),从(n)中去掉所有(i)并做记录,就能求出(n)的质因数.

    for(int i=2;i<=sqrt(n);i++) {
        while(n%i==0) {
            n/=i;
            cnt[i]++;
        }
    }
    

    时间复杂度(O(sqrt n))

    欧拉函数

    欧拉函数是从(1)(n-1)的数中与(n)互质的数的个数.
    (φ(1)=φ(2)=1).

    性质

    1. 对于质数(n),(φ(n)=n-1).
    2. 对于质数(p),(φ(p^k)=(p-1)*p^{k-1}).
    3. 对于互质的(n,m),(φ(n)*φ(m)=φ(n*m)).
    4. 对于奇数(n),(φ(2*n)=φ(n)).
    5. 对于(n(n>1)),(sum_{k=1}^n{k(gcd(n,k)=1)}=φ(n)*n/2).
    6. (k\%p=0),(φ(k*p)=φ(k)*p).
    7. (k\%p!=0),(φ(k*p)=φ(k)*(p-1)).
    8. 对于互质的(a,m),(a^{φ(p)} equiv 1 pmod {p}).
    9. (sum_{kmid n}^n{φ(k)}=n)
    10. (φ(n)=sum_{kmid n}^n{φ(k)*frac{n}{k}}).

    计算公式及证明

    (n)的质因数分解为(p_1^{c_1}*p_2^{c_2}*)...(*p_i^{c_i}).
    (φ(n)=n*frac{p_1-1}{p_1}*frac{p_2-1}{p_2}*)...(*frac{p_i-1}{p_i})
    证明:设(p,q)(n)的质因子.
    (1)-(n)中,(p)的倍数有(frac{n}{p})个,(q)的倍数有(frac{n}{q})个,(p*q)的倍数有(frac{n}{p+q})个.
    所以(1)(n-1)中与(p,q)互质的数的个数为
    (egin{align*} n-frac{n}{p}-frac{n}{q}+frac{n}{p*q}&=n*(1-frac{1}{p}-frac{1}{q}+frac{1}{p*q})\ &=n*(1-frac{1}{p})*(1-frac{1}{q}) end{align*})
    其他质因子同理.

    算法实现

    对于求单个欧拉函数,分解质因数即可.

    for(long long i=2;i<=sqrt(num);i++) {
        bool div=false;
        while(num%i==0) {
            div=true;
            num/=i;
        }
        if(div) ans=ans*(i-1)/i;
    }
    if(num>1) ans=ans*(num-1)/num;
    

    时间复杂度与质因数分解一样.
    但如果要求从(1)(n)的数的欧拉函数,就可以通过打表法来求解.

    for(int i=2;i<=MAXN;i++) {
        if(!phi[i]) {
            for(int j=i;j<=MAXN;j+=i) {
                if(!phi[j]) phi[j]=j;
                phi[j]=phi[j]/i*(i-1);
            }
        }
    }
    

    或是在欧拉筛时同时求出欧拉函数.

    for(int i=2;i<=n;i++){
        if(!vis[i]) {
            cnt++;
            pri[cnt]=i;
            phi[cnt]=i-1;
        }
        for(int j=1;i*pri[j]<=n;j++){
            vis[i*pri[j]]=true;
            if(i%pri[j]==0) {
                phi[i*pri[j]]=phi[i]*pri[j];
                break;
            }
            phi[i*pri[j]]=phi[i]*(pri[j]-1);
        }
    }
    
    不忘初心 砥砺前行
  • 相关阅读:
    SpringBoot 添加JSP支持
    SpringBoot的过滤器和拦截器和全局异常处理
    SpringBoot日志配置-logback和log4j2
    SpringBoot使用thymeleaf模板
    乐观锁与悲观锁
    js中的val extinner 的区别
    centos7安装最新版node和npm
    ES2020,你需要知道的一切内容!
    U盘弹出文件或目录损坏且无法读取实测解决教程
    MySQL远程连接丢失问题解决方法
  • 原文地址:https://www.cnblogs.com/gzezfisher/p/prime.html
Copyright © 2011-2022 走看看