[学习笔记]线性筛

介绍了欧拉筛法的基本原理及其线性复杂度特性,利用该方法可以有效地筛选出素数并计算积性函数如欧拉函数和莫比乌斯函数的值。通过具体的实现代码展示了如何进行高效计算。

素数

欧拉筛法保证每个合数只会被其最小的素数筛掉,所以复杂度是线性的。

我们还能用此方法,筛出其他一些积性函数的值。

积性函数:若(a,b)=1,则f(ab)=f(a)\;\times\;f(b).

int p[N],n,cnt;
bool b[N];
inline void prime(){
    b[0]=b[1]=true;
    for(int i=2;i<=n;++i){
        if(!b[i]) p[++cnt]=i;
        for(int j=1;j<=cnt&&i*p[j]<=n;++j){
            b[i*p[j]]=true;
            if(!(i%p[j])) break;
        }        
    }
}

每次p[j]|i时跳出循环能保证每个合数只会被其最小的素数筛掉,因为i$\times$p[k](k>j)的最小素数为p[j]

欧拉函数

欧拉函数$\phi(x)的定义:小于等于x的正整数中与x互质的数的个数。

\phi(x)=\begin{cases}1&x=1\\x-1&x\;is\;prime\\ x\prod_{i=1}^{k}\(\frac{p_{i}-1}{p_{i}}\)&x=p_1^{a_1}$\times$p_2^{a_2}$\times\dots\times$p_k^{a_k}\\\end{cases}

证明:

  • 如果n为某一素数p,则\phi(p)=p-1.
  • 如果n为某一素数p的幂次p^a\phi(p^a)=(p-1)\;\times\;p^{a-1}.
  • 欧拉函数是积性函数,即当(a,b)=1f(ab)=f(a)\;\times\;f(b).
  • x=p_1^{a_1}$\times$p_2^{a_2}$\times\dots\times$p_k^{a_k},

  则\phi(x)=\prod_{i=1}^{k}(p_i-1)\;\times\;p_i^{a_i-1}=x\prod_{i=1}^{k}\frac{p_i-1}{p_i}.

px最小的质数,x'=x/p,在线性筛中,x被筛p$\times$x'掉。

x'\;mod\;p\not=0时,\phi(x)=p$\times$x'\times\(\frac{p-1}{p}\)\prod_{i=1}^{k'}\(\frac{p_{i}-1}{p_{i}}\)=(p-1)\times\phi(x')

x'\;mod\;p=0时,\phi(x)=p$\times$x'\times\prod_{i=1}^{k'}\(\frac{p_{i}-1}{p_{i}}\)=p\times\phi(x')

int p[N],phi[N],n,cnt;
bool b[N];
inline void prime(){
    b[0]=b[1]=true;phi[1]=1;
    for(int i=2;i<=n;++i){
        if(!b[i]){
            p[++cnt]=i;phi[i]=i-1;
        }
        for(int j=1;j<=cnt&&i*p[j]<=n;++j){
            b[i*p[j]]=true;
            if(!(i%p[j])){
                phi[i*p[j]]=p[j]*phi[i];break;
            }
            phi[i*p[j]]=(p[j]-1)*phi[i];
        }        
    }
}

莫比乌斯函数

莫比乌斯函数\mu(x)的定义:

\mu(x)=\begin{cases}1&x=1\\ (-1)^{k}&x=p_{1}^{a_{1}}p_{2}^{a_{2}}\;\dots\;p_{k}^{a_{k}}(a_{i}=1)\\ 0&x=p_{1}^{a_{1}}p_{2}^{a_{2}}\;\dots\;p_{k}^{a_{k}}(max\{a_{i}\}>1)\end{cases}

显然当x是质数时,\mu(x)=-1

x不是质数时,px最小的质数,x'=x/p,在线性筛中,x被筛p$\times$x'掉。

x'\;mod\;p\not=0时,当\mu(x')\not=0时,显然a_{i}=1\mu(x)=-\mu(x')

               当\mu(x')=0时,\mu(x)=0,即\mu(x)=-\mu(x')

x'\;mod\;p=0时,显然max\{a_{i}\}>1\mu(x)=0

int p[N],mu[N],n,cnt;
bool b[N];
inline void prime(){
    b[0]=b[1]=true;mu[1]=1;
    for(int i=2;i<=n;++i){
        if(!b[i]){
            p[++cnt]=i;mu[i]=-1;
        }
        for(int j=1;j<=cnt&&i*p[j]<=n;++j){
            b[i*p[j]]=true;
            if(!(i%p[j])){
                mu[i*p[j]]=0;break;
            }
            mu[i*p[j]]=-mu[i];
        }        
    }
}

转载于:https://www.cnblogs.com/AireenYe/p/5821028.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值