线性筛各种数

怎么筛质数?有一种很简单的方法,1到n枚举,是质数就把他所有的倍数打一个合数标记,然后就完了。但是我们有一个问题,比如说30,它会被2筛掉,被3筛掉,被5筛掉。这样复杂度就不会很优秀,我们有什么做法让30只被2筛,不被3和5筛掉呢?

于是我们换一种筛法,据说叫做欧拉筛。就是对于每一个数,我们用小于它的质数乘上它,然后把那个数筛掉。重要的是,如果这个数可以整除当前质数,就break掉。这样我们就很惊奇地发现,每个数我们都筛且只筛了一次。这是为什么呢,我们再画一个图。
这里写图片描述

上面筛不到,下面一定有一个把它筛掉对不对?而且这么做有一个性质,我们可以保证每一个数都被它最小的质数筛掉。这样,我们发现积性函数是非常好筛的。比如说 miu m i u (莫比乌斯函数),我们分三种情况讨论一下:

1.x是一个质数: miu(x)=1 m i u ( x ) = − 1

2.x最小的质数只有一次,记它为 p,miu(x)=miu(xp)miu(p) p , m i u ( x ) = m i u ( x p ) ∗ m i u ( p ) 因为是积性函数, xp x p p p 互质

3.x最小的质数不止一次,miu(x)=0

很显然,我们线筛的时候有一个质数表作为副产品。

贴一波代码

void shai()  
{  
    vis[1]=1;miu[1]=1;//特殊处理1的情况   
    for(int i=2;i<=n;i++)  
    {  
        if(vis[i]==0) p[++cnt]=i,miu[i]=-1;//质数情况,miu为-1   
        for(int j=1;j<=cnt&&i*p[j]<=n;j++)  
        {  
            if(i%p[j]==0)//可以整除的话,最小质数至少次数为2,所以miu为0   
            {  
                vis[i*p[j]]=1;  
                miu[i*p[j]]=0;  
                break;//保证复杂度为O(1)   
            }  
            miu[i*p[j]]=miu[i]*miu[p[j]];//不能整除,两个互质,则满足积性函数条件   
            vis[i*p[j]]=1;  
        }  
    }  
}  

所有线筛的板子都是这样的,可以思考一下 phi p h i (欧拉函数)的筛法。
然后我们还可以拓展一下,我们不止可以筛积性函数,还可以筛一些非积性函数。

比如这个函数: f(x)=x f ( x ) = x 分解质因数的最高次幂,特殊的 f(1)=0 f ( 1 ) = 0

1.质数情况: f(x)=1 f ( x ) = 1

2.x最小的质数只有一次,记它为 pf(x)=max{f(xp),1} p , f ( x ) = m a x { f ( x p ) , 1 }

3.x最小的质数不止一次,记它为 p p ,记它的次数为c f(x)=max{f(xp),c} f ( x ) = m a x { f ( x p ) , c }

那么问题来了,我们如何才能 O(1) O ( 1 ) 查询 c c 咧?所以我们还要和f一起筛 c c

1.质数情况:c(x)=1

2. x x 最小的质数只有一次:c(x)=1

3. x x 最小的质数不止一次,记它为p:c(xp)+1

然后我们把质数 ,fc , f , c 一起筛,就可以 O(n) O ( n ) 得到 f f 了。

总结一下,线性筛法不止可以筛积性函数,还可以筛一些有特点的非积性函数,这些函数一般与因数或者质因数有关。判断一个函数是否可以线性筛,我们不需要判断它是不是积性函数,我们只要判断它在以上三种情况的取值就行。但是在某些情况十分复杂的时候,我们很难笔算出各情况的取值。于是我们可以O(n2)打表找一找规律,有时候有奇效。可能笔算很难推的式子规律却很简单。不过值得注意的是,打表也不一定找得到规律,找规律的时候一定要大开脑洞。具体情况还是要具体分析,对于不同的题目可能用不同的方法,会简化很多。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值