线性筛素数and欧拉函数

本文介绍了线性筛法(欧拉筛法)和欧拉函数的概念及应用。通过线性筛法可以实现O(n)的时间复杂度求解素数,而欧拉函数则表示小于一个数且与该数互质的数的个数。文章详细讲解了如何使用线性筛法求解欧拉函数,并提供了两种特殊情况的处理:当x为质数幂时和当x为奇数时。此外,还提到了求单个和大量欧拉函数值的方法。
摘要由CSDN通过智能技术生成

好久没打博客了。。。。_ (:зゝ∠) _,毕竟狗出竞赛。。。


最近题目都涉及到素数的问题,发现自己连个线筛都不会,赶紧去看了一波。虽说一下子就看懂了。

正题

一般遇到个数,要判断是否为素数。
这从刚学时就开始了。。。。

方法一:

从2~n-1枚举,看是否有一个i使得n%i==0,没有即为素数。
时间O(n)最蠢的

方法二:

从2~sqrt(n)里枚举。因为若存在一个大于sqrt(n)的数能整除n,n/sqrt(n)一定是一个<=sqrt(n)的数,所以在前面一定会被枚举到。
时间O( n ).

还有什么其他的“米勒拉宾素数测试的方法”根本就不会,不理它了。


然而现实中并不一定只让你求一个素数,而是让你求一堆的素数。
这时常用的办法为:筛法

方法一:Eratosthenes筛法

如果一个数是素数,那它的倍数就不是素数,对此进行筛法。

    memset(bz,true,sizeof(bz));
    fo(i,2,n)
    if (bz[i]){
        fo(j,2,n/i) bz[i*j]=false;
    }

速度为O(n* log log n)。
但是其中比如6会在2,3时都被筛一次,就是冗余情况,浪费了时间。

方法二(important):欧拉筛法(线性筛法)

上面的筛法中,时间浪费在一个数会被多个数筛去。
那我们就保证对于一个数x,我们用它最小的质因数i去筛掉它,就可以达到O(n)的速度。

实现为:我们现在枚举到一个素数x,我们就从之前找到素数表里素数i,然后用它们去筛掉数x*i。当x%i==0时,就停止筛选。可以证明,这样就可以保证每个数只会被筛一次。(证明很多人写,就不写了)。
(空想一下,设n1=x* i1,n2=x* i2(i1 < i2),若x%i1==0的话,那n2%i1==0,这样n2就可以用i1去筛)。

    fo(i,2,sum) {
        if (!bz[i]) pri[++num]=i;
        fo(j,1,num){
            if (pri[j]*i>sum) break;
            bz[pri[j]*i]=true;
            if (i%pri[j]==0) break;
        }
    }

时间为O(n),很快的。


借此筛法,我们可以求欧拉函数了!
欧拉函数:用 ϕ(x)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值