zoukankan      html  css  js  c++  java
  • [学习笔记]线性筛

    素数

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

    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]\)

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

    积性函数

    \((a,b)=1\),则\(f(ab)=f(a)\;\times\;f(b)\).

    欧拉函数

    欧拉函数\(\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)=1\)\(f(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}\).

    \(p\)\(x\)最小的质数,\(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\)不是质数时,设\(p\)\(x\)最小的质数,\(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];
            }
        }
    }
    
  • 相关阅读:
    C语言打印记事本内搜索字符串所在行信息
    原创:C语言打开、下载、删除网页,统计网页字符个数
    JAVA GUI编程学习笔记目录
    13.JAVA之GUI编程将程序打包jar
    12.JAVA之GUI编程打开与保存文件
    11.JAVA之GUI编程菜单
    10.JAVA之GUI编程弹出对话框Dialog
    php中的一些不常见的问题foreach/in_array[开发篇]
    微软职位内部推荐-Senior SDE
    微软职位内部推荐-SDE II
  • 原文地址:https://www.cnblogs.com/AireenYe/p/LinearSieve.html
Copyright © 2011-2022 走看看