zoukankan      html  css  js  c++  java
  • [日常摸鱼]一些素数筛法(暴力筛/埃氏筛/欧拉筛)与复杂度证明

    昨天晚上突然发现不会证埃氏筛的复杂度,去研究了一下就有了这篇博客。

    首先最朴素的筛法,对每个(i=1,dots,n),再枚举一个(j=1,dots,lfloorfrac{n}{i} floor),去筛掉(i*j),这样是一个(O(nlog n))的复杂度。

    接着是埃氏筛,每次只对素数(i),把(i imes pri[j])筛一遍,复杂度于是(egin{aligned}sum_{1leq pleq n (pin prime)} frac{1}{p}end{aligned}),级别的,可以证明这个式子是(O(nlog log n))的:

    (f(x))是一个在([l,r])连续可微的函数,(A(n)=sum_{ileq n}a_i),类似分部积分的操作,(A_{i}f_{i}-A_{i-1}f_{i-1}=(A_i-A_{i-1})f_i+A_{i-1}(f_{i}-f_{i-1})=a_{i}f_i+A_{i-1}(f_{i}-f_{i-1})),两边求和得到:(egin{aligned}A_rf_r-A_l f_l=sum_{i=l+1}^ra_if_i+sum_{i=l+1}^r A_{i-1}(f_i-f_{i-1})end{aligned})

    为了方便,后面那个(sum)经常还能换成积分:(=egin{aligned}sum_{i=l+1}^r A_i int_{i-1}^{i}f'(t)dt=int_l^r A_t f'(t)dtend{aligned}),于是有:(egin{aligned}sum_{i=l+1}^r a_i f_i=A_r f_r-A_l f_l -int_l^r A_t f'(t)dtend{aligned}),接着在这里,我们令(a_i)表示(i)是不是素数(是的话为1,否则为0),于是(A(n)=pi(n)),再取(f_i=frac{1}{i}),取(l=2)开始求和,就得到了素数倒数和(egin{aligned}sum_{pleq n}frac{1}{p}=frac{pi(n)}{n}+int_2^nfrac{pi(t)}{t^2}dtend{aligned}),接着我们近似地用(pi (x)sim frac{x}{ln x})来算积分,就得到了(O(nlog log n))这个结果啦

    欧拉筛则是考虑对每个数(i)枚举比他小素数(j),把(i imes j)筛掉,与此同时,一旦发现(j|i)就结束这一轮(j)的枚举,这样就能保证每个数字最多只被筛一次,复杂度是严格的(O(n))的。

    同时我们说这种方法能用来筛一些像是莫比乌斯函数/欧拉函数这样的积性函数(即(n,m)互质时,符合(f(nm)=f(n)f(m))的一类函数)。

  • 相关阅读:
    Java Stream 流(JDK 8 新特性)
    Java EnumMap 实现类
    Java 设计模式
    Java lambda 表达式详解(JDK 8 新特性)
    Java forEach 方式遍历集合(Java 8 新特性)
    Java 单例设计模式
    Java public 和 private 访问修饰符
    == 、equals 、hashcode
    String
    ClassLoader 的分类及加载顺序
  • 原文地址:https://www.cnblogs.com/yoshinow2001/p/14610848.html
Copyright © 2011-2022 走看看