质数

质数的定义

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

质数的判断

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

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

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

质数筛法

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

暴力

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

埃氏筛法

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

欧拉线性筛法

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

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 ) O(n) O(n)

质因数分解

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

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

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

欧拉函数

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

性质

  1. 对于质数 n n n, φ ( n ) = n − 1 φ(n)=n-1 φ(n)=n1.
  2. 对于质数 p p p, φ ( p k ) = ( p − 1 ) ∗ p k − 1 φ(p^k)=(p-1)*p^{k-1} φ(pk)=(p1)pk1.
  3. 对于互质的 n , m n,m n,m, φ ( n ) ∗ φ ( m ) = φ ( n ∗ m ) φ(n)*φ(m)=φ(n*m) φ(n)φ(m)=φ(nm).
  4. 对于奇数 n n n, φ ( 2 ∗ n ) = φ ( n ) φ(2*n)=φ(n) φ(2n)=φ(n).
  5. 对于 n ( n > 1 ) n(n>1) n(n>1), ∑ k = 1 n k ( g c d ( n , k ) = 1 ) = φ ( n ) ∗ n / 2 \sum_{k=1}^n{k(gcd(n,k)=1)}=φ(n)*n/2 k=1nk(gcd(n,k)=1)=φ(n)n/2.
  6. k % p = 0 k\%p=0 k%p=0, φ ( k ∗ p ) = φ ( k ) ∗ p φ(k*p)=φ(k)*p φ(kp)=φ(k)p.
  7. k % p ! = 0 k\%p!=0 k%p!=0, φ ( k ∗ p ) = φ ( k ) ∗ ( p − 1 ) φ(k*p)=φ(k)*(p-1) φ(kp)=φ(k)(p1).
  8. 对于互质的 a , m a,m a,m, a φ ( p ) ≡ 1 ( m o d p ) a^{φ(p)} \equiv 1 \pmod {p} aφ(p)1(modp).
  9. ∑ k ∣ n n φ ( k ) = n \sum_{k\mid n}^n{φ(k)}=n knnφ(k)=n
  10. φ ( n ) = ∑ k ∣ n n φ ( k ) ∗ n k φ(n)=\sum_{k\mid n}^n{φ(k)*\frac{n}{k}} φ(n)=knnφ(k)kn.

计算公式及证明

n n n的质因数分解为 p 1 c 1 ∗ p 2 c 2 ∗ p_1^{c_1}*p_2^{c_2}* p1c1p2c2 ∗ p i c i *p_i^{c_i} pici.
φ ( n ) = n ∗ p 1 − 1 p 1 ∗ p 2 − 1 p 2 ∗ φ(n)=n*\frac{p_1-1}{p_1}*\frac{p_2-1}{p_2}* φ(n)=np1p11p2p21 ∗ p i − 1 p i *\frac{p_i-1}{p_i} pipi1
证明:设 p , q p,q p,q n n n的质因子.
1 1 1- n n n中, p p p的倍数有 n p \frac{n}{p} pn个, q q q的倍数有 n q \frac{n}{q} qn个, p ∗ q p*q pq的倍数有 n p + q \frac{n}{p+q} p+qn个.
所以 1 1 1 n − 1 n-1 n1中与 p , q p,q p,q互质的数的个数为
KaTeX parse error: No such environment: align* at position 7: \begin{̲a̲l̲i̲g̲n̲*̲}̲ n-\frac{n}{p}-…
其他质因子同理.

算法实现

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

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 1 1 n n 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);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值