{算法}乱谈线性筛法

Concept

指在线性时间 O(n) 筛选的方法求一些东西的算法。
伪目录
1. 求质数表
2. 筛出欧拉函数φ


Ideas

As we all know, x=p1a1p2a2...pnan x=ni=1piai
其中 pii,ai
我们还可以通过乘法定理得知, xni=1(ai+1)
当然,这是后话了

For prime Numbers table

最简单的,我们使用线性筛法质数表
先来看看普通的筛法

fillchar(x,sizeof(x),true);//假设所有数都是质数(Tips x[1]=false)
for i:=2 to n do
if x[i] then  //x[i]表示i是否为质数
    for j:=2 to n div i do
    x[i*j]:=false;  //筛掉i*j(非质数)

显然复杂度为 O(n2)
我们发现,有的数字被筛了多次,如24
当然最好的情况是每个数字只被筛1次

看Code之间,先回忆一句话

使每个数字只被筛1次

也许我们需要换个思路(线性筛法)
线性筛法又是如何做到使每个数字只被筛1次的呢?
这就是我们所需要证明的

Code
fillchar(bz,sizeof(bz),true);
for i:=2 to n do//枚举数i
begin
    if(bz[i])then//i为素数
    begin
        inc(tot);
        s[tot]:=i;//素数数组
    end;
    for j:=1 to tot do
    begin 
        bz[i*s[j]]:=false;//筛去i*s[j]
        if(i mod s[j]=0)then break;//什么鬼?怎么就Break了?
    end;
end;

相信都对if(i mod s[j]=0)then break;一脸懵逼吧~
这也正是线性筛法的神奇所在

好了不说废话
用上 x=ni=1piai

为使令循环break掉的就是 p1 (最小的素数)
不能让 xpl(l>1)
x=p1a=plb

plb=ni=1piaib
=(up2p3...pm1pm)p1
=ap1
显然 a<b

a没有比 p1 要小的质因数
一定会枚举到 b 前用a x=ap1=bpl 筛掉。
每个 x 只会被p1a筛掉

至于某些人问会不会筛掉质数……
我推荐给你一个小学奥数班!

筛出欧拉函数φ

读作φ(fai)
φ(n)为小于n并与n互质的数的个数,是积性函数
gcd(a,b)=1φ(ab)=φ(a)φ(b)
φ(1)=1

性质
  1. xφ(x)=x1
    小于 x 的数不都与x互质吗?
  2. xφ(xk)=xkxkx=xk1(x1)
    显然只有 x 的倍数才不互质xk
  3. φ(x)=kj=1φ(pjaj)
    φ(x) 为积性函数
于是乎~

x=p1
性质2
φ(xk)=xk1(x1)
φ(xk+1)=xk(x1)

φ(xk+1)=φ(xk)x
φ(xi)
=φ(xa1+1)φ(p2a2)....φ(pkak)
=xφ(xa1)φ(p2a2)....φ(pkak)
=xφ(i)
x|iφ(ix)=φ(i)x
φ(ix)=φ(i)φ(x)=φ(i)(x1)

Code

恕暂不提供Pascal语言

int prime[M/3],phi[M];  
bool flag[M];  
void get_prime()  
{  
    int i,j,k;  
    memset(flag,false,sizeof(flag));  
    k=0;  
    for(i=2;i<M;i++){  
        if(!flag[i]){                              
            prime[k++]=i;  
            phi[i]=i-1;  
        }  
        for(j=0;j<k&&i*prime[j]<M;j++){  
            flag[i*prime[j]]=true;              
            if(i%prime[j]==0){  
                phi[i*prime[j]]=phi[i]*prime[j];  
                    break;  
            }  
            else  
                phi[i*prime[j]]=phi[i]*(prime[j]-1);  
        }  
    }  
}

Reference

线性筛法求素数的原理与实现 百度文库
约数详细分析By ColdChair
线性筛法相关By jokerwyt
线性筛法求素数By XianHaoMing

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值