一些些筛子(埃氏筛、线性筛、杜教筛)

这篇具有很好参考价值的文章主要介绍了一些些筛子(埃氏筛、线性筛、杜教筛)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

有时我们需要求出一个范围内的质数,或者要计算一些积性函数的值,但往往题目无法承受直接判断质数、直接求函数值的时间复杂度,这时我们就可以用筛子了

入门级:埃氏筛

假设当前有一块板,板上写着 \(2\sim n\) 的数,如果我们想快速找出质数,那么我们可以考虑标记那些合数,让划了斜线的数表示合数,于是我们从左往右依次看,当遇到一个质数时,就把后面他的所有的倍数都划上斜线,而这就是埃氏筛的原理

for(int i = 2; i <= n; i++)
    if(st[i] == 0)//判断是否为质数
        for(int j = 2 * i; j <= n; j += i)
            st[j] = 1; // j是i的一个倍数,j是合数,筛掉。

这是埃氏筛的简单实现,但我们又会发现,枚举一个更大的质数 \(i\) 的倍数时,假设当前乘的 \(j\),若 \(j < i\) 那么当前枚举的这个倍数肯定会被之前的更小的质数枚举到,于是能够进一步优化:

//更快写法:
for(int i = 2; i <= n / i; i++)
    if(st[i] == 0)
        for(int j = i * i; j <= n; j += i)
            st[j] = 1; // j是i的一个倍数,j是合数,筛掉。

两个代码的时间复杂度分别为 \(O(n\log\log n)\)、(带点常数但近似于)\(O(n)\)

埃氏筛还是比较容易理解的,所以新手一般建议使用埃氏筛 QwQ

进阶:欧拉筛/线性筛

for(int i = 2; i <= n; ++i) {
    if(!vis[i]) pri[++cnt]=i;
    for(int j = 1; j <= cnt && pri[j] <= B/i; ++j) {
        vis[pri[j]*i]=1;
        if(i%pri[j] == 0) 
            break;
    }
}

其实,埃氏筛即使是第二种写法依旧会给一些合数进行多次筛除操作,比如在筛 \(24\) 时,先用 \(2\times12\) 筛了一次,但又用 \(3\times 8\) 筛了一次,所以我们使用欧拉筛,每次给当前数乘上一个质数使得乘质数为乘积的最小质因数,这样每个数就只会被筛一次了,因此时间复杂度为线性,\(O(n)\),线性筛常用于求欧拉函数 \(\varphi\)、莫比乌斯函数 \(\mu\) 这些积性函数

特殊的筛

下面的筛子(目前只写了杜教筛 QwQ)用于一些特殊的用途,比如求积性函数的前缀和等等,算是高级算法

杜教筛

若现在要求积性函数 \(f\) 的前缀和,设 \(S(n)=\sum_{i=1}^nf(i)\),再找一个积性函数 \(g\),则考虑它们的狄利克雷卷积的前缀和:

\[\begin{aligned} &\sum_{i=1}^n\big(f+g\big)(i)\\ =&\sum_{i=1}^n\sum_{d|i}f(d)g(\frac{i}{d})\\ =&\sum_{d=1}^ng(d)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}f(i)\\ =&\sum_{d=1}^ng(d)S(\lfloor\frac{n}{d}\rfloor)\\ \end{aligned} \]

会发现 \(d=1\) 时,\(\lfloor\frac{n}{d}\rfloor=n\),那么:

\[g(1)S(n)=\sum_{i=1}^n\big(f*g\big)(i)-\sum_{i=2}^n g(d)S(\lfloor\frac n d\rfloor) \]

这就是杜教筛的核心式子了,在求积性函数 \(f\) 的前缀和 \(S\) 时,我们可以选择合适的积性函数 \(g\) ,使得函数 \(g\)\(\sum_{i=1}^n\big(f*g\big)(i)\) 的值方便计算,从而快速地数论分块+递归+记忆化算出 \(S(n)\)

当线性筛先筛到 \(n^{\frac 2 3}\) 时,杜教筛的时间复杂度为 \(O(n^{\frac 2 3})\),硬跑的时间复杂度为 \(O(n^{\frac 3 4})\)

ll GetSum(int n) { // 算 f 前缀和的函数
  ll ans = f_g_sum(n); // 算 f * g 的前缀和
  // 以下这个 for 循环是数论分块
  for(ll l = 2, r; l <= n; l = r + 1) { // 注意从 2 开始
    r = (n / (n / l)); 
    ans -= (g_sum(r) - g_sum(l - 1)) * GetSum(n / l);
    // g_sum 是 g 的前缀和
    // 递归 GetSum 求解
  } return ans; 
}

μ 的前缀和

因为 \(\mu*\pmb 1=\epsilon\),所以取 \(f=\mu,\ g=\pmb 1\)

\(\varphi\) 的前缀和

因为 \(\varphi*\pmb 1=Id\),所以取 \(f=\varphi,\ g=\pmb 1\)

\(\varphi*Id\) 的前缀和

由于 \(\Big(\big(\varphi*Id\big)*Id\Big)(n)=\sum_{d|n}\varphi(d)\times d\times\frac{n}{d}=n\times\sum_{d|n}\varphi(d)=n^2\),所以取 \(f=\varphi*Id,\ g=Id\)文章来源地址https://www.toymoban.com/news/detail-746025.html

到了这里,关于一些些筛子(埃氏筛、线性筛、杜教筛)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • POJ 2429 Miller-rabin素数判定 + pollard-rho质因子分解 + 埃氏筛法

    题目不能说是很难,只是用到了许多数学上的知识(费马小定理,miller-radin,pollard-rho),还有一些算法上的知识DFS,辗转相除。 我也很菜,一个周末的时间都用在这个题目上了,但写了很多很多的注释,花费了大量的篇幅,浅谈了我对这些算法的拙见,希望能够帮助大家!

    2024年02月13日
    浏览(40)
  • [Go版]算法通关村第十三关黄金——数字数学问题之数论问题(最大公约数、素数、埃氏筛、丑数)

    题目链接:LeetCode-1979. 找出数组的最大公约数 辗转相除法其核心部分为:若r 是a ÷ b的余数,则 gcd(a, b)=gcd(b, r) 题目链接:LeetCode-204. 计数质数 如果 x 是质数,那么大于 x 的 x 的倍数 2x,3x,… 一定不是质数。 时间复杂度分析: 外层循环的迭代次数是 n-2,即 O ( n ) O(n) O ( n ) 次

    2024年02月11日
    浏览(39)
  • 线性代数的一些小细节

    1 .矩阵乘法满足结合律,但不满足交换律。 如下图中,UWQ三个矩阵,(UW)Q 和U(WQ)的2种结合,证明矩阵乘法满足结合律。 AB 和BA的表达式,如下图中,相同的条件是对应的8项都相同(两个对称矩阵必然满足条件),但是实际上,矩阵展开后的x和y位置是是转置的,只有对角线上

    2024年02月16日
    浏览(36)
  • 2023Robocom睿抗(本科组省赛)3-筛子游戏

    在某个游戏中有一个骰子游戏。在游戏中,你需要投掷 5 个标准六面骰子(骰子为一个正方体,6 个面上分别有1、2、3、4、5、6中的一个数字,骰子的质量均匀),投出的点数根据组合会获得一个“获胜等级”。获胜等级从高到低如下: 五个同点数 - 五个骰子显示相同的点数

    2024年02月17日
    浏览(32)
  • 信号与系统的一些基本问题之信号分解完备正交基[1]—线性代数向量空间与向量基的基础

      由于一些前后概念是嵌套在一起,密切相关的,但是它们的认知深度的层次又有先后差异,所以为循序渐进,这里在讲解时会存在部分的后面的概念往前提以帮助当前概念的理解以确保大家每一步都能看得懂,并为后续概念作铺垫,文中所有存在这种概念嵌套的情况都有

    2024年04月26日
    浏览(53)
  • vscode 的代码提示有时候有,有时候没有(python)

    vscode 的代码提示有时候有,有时候没有。没有的时候出现如下报错: Sorry, something went wrong activating IntelliCode support for Python. Please check the “Python” and “VS IntelliCode” output windows for details. 不太清楚为什么,把 IntelliCode 的版本换了别的也不好用。 先存一下,以后遇到解决方法

    2024年02月09日
    浏览(80)
  • el-input有时候添加不了有时候删不了

    有些情况下在 el-input 是无法输入的,绑定的值动也动不了,删也删不掉,改也改不了可能是以下原因导致 Tips:我出现的问题是通过问题一解决~~~

    2024年02月07日
    浏览(61)
  • 图片链接或pdf链接通过浏览器打开时,有时可以直接预览,有时却是下载,为什么?

    在前端开发中,有时候需要对一些文件链接进行特殊处理,比如对于一些图片链接或者PDF链接,有时我们需要通过浏览器打开进行预览,有时又不希望通过浏览器进行打开,而是希望能够直接下载到本地。但现实效果却往往跟我们相反,我们希望浏览器打开时,他却直接下载

    2024年02月10日
    浏览(66)
  • 【Unity】拖拽放置模型时 为什么出现有时候有紧贴地面和有时候随机再空中的情况

    👨‍💻个人主页 :@元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 😶‍🌫️收录于专栏 :unity细节和bug 😶‍🌫️优质专栏 ⭐【软件设计师高频考点暴击】 解决了点个赞,关注下吧✅ ⭐【2023unity游戏制作-mango的冒险】-开始画面API制作 ⭐【

    2024年02月10日
    浏览(56)
  • kafka消费数据,有时消费不到原因?

    Kafka消费数据时有时消费不到的原因可能包括以下几点: 1:配置问题:首先需要检查Kafka的配置是否正确,比如是否设置了group.id ,对应的topic是否正确等。如果消费者尝试消费不存在的主题,则会发生错误。 2:消费者群组配置错误:如果消费者所属的消费群组配置错误,也

    2024年04月23日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包