zoukankan      html  css  js  c++  java
  • 我也不知道什么是"莫比乌斯反演"和"杜教筛"

    upd:正在写一篇复习向的文章,之后贴链接,可以作为这篇文章的一个补充。
    upd:写好啦,戳这里。新写的这篇复习向文章QwQ,可以当做一个补充来看吧。不过新写的文章也有我新的理解吧。

    Part0

    最近一直在搞这些东西
    做了将近20道题目吧
    也算是有感而发
    写点东西记录一下自己的感受

    如果您真的想学会莫比乌斯反演和杜教筛,请拿出纸笔,每个式子都自己好好的推一遍,理解清楚每一步是怎么来的,并且自己好好思考。

    Part1莫比乌斯反演

    莫比乌斯反演啥都没有,就只有两个式子(一般只用一个)
    原来我已经写过一次了,再在这里写一次
    就只写常用的那个吧

    基本的公式


    对于一个函数(f(x))
    (g(x)=sum_{x|d}f(d))
    那么

    [f(x)=sum_{x|d}mu(frac{d}{x})g(d) ]


    这个有什么用?
    似乎太有用了一点

    随手搞道题目来说吧


    求$$sum_{i=1}^nsum_{j=1}^m[gcd(i,j)=1]$$

    这个东西很直接,
    所以我们设$$f(x)=sum_{i=1}^nsum_{j=1}^m[gcd(i,j)=x]$$

    [g(x)=sum_{x|d}f(d) ]

    根据莫比乌斯反演可以得到

    [f(1)=sum_{1|d}mu(frac{d}{1})g(d)=sum_{i=1}^nmu(i)g(i) ]

    (g(x))是什么东西?

    [g(x)=sum_{i=1}^nsum_{j=1}^m[x|gcd(i,j)] ]

    直接把(x)除到上面去

    [g(x)=sum_{i=1}^{n/x}sum_{j=1}^{m/x}[1|gcd(i,j)] ]

    ([1|gcd])显然成立的
    所以(g(x)=[frac{n}{x}][frac{m}{x}])
    可以(O(1))计算
    所以,(f(1))可以(O(n))计算


    一起推下式子

    莫比乌斯反演的套路太多了

    我们再来看两道题目
    Crash的数字表格
    jzptab

    这两题按照顺序看嗷

    具体的过程直接看我博客里面写的东西

    我们发现这两道题一模一样
    但是下面的那道题目可以做到单次询问(O(sqrt n))

    他多干了什么???
    这个问题,我们自己再来重新推一下
    不过找个容易点的东西


    [sum_{i=1}^nsum_{j=1}^mgcd(i,j) ]

    这个肯定没有前面我给的例子的莫比乌斯反演那么直接
    但是我们观察一下,(gcd)的取值有哪些??
    (1~n)(假设(n<m))
    那么,我们可以把(gcd)相同的项合并

    所以,我们枚举(gcd)的值

    [sum_{d=1}^ndsum_{i=1}^nsum_{j=1}^m[gcd(i,j)=d] ]

    后面的那一部分是不是想到了前面推出的东西???
    所以先把(d)直接除上去

    [sum_{d=1}^ndsum_{i=1}^{n/d}sum_{j=1}^{m/d}[gcd(i,j)=1] ]

    (n/d)(m/d)不要想太多,你就当成(x)(y)

    [sum_{i=1}^{x}sum_{j=1}^{y}[gcd(i,j)=1] ]

    不就是上面推过的第一个例子??

    [=sum_{i=1}^xmu(i)[frac{x}{i}][frac{y}{i}] ]

    把这一截放回我们要求的式子里面去

    [sum_{d=1}^ndsum_{i=1}^{x}mu(i)[frac{x}{i}][frac{y}{i}] ]

    (x,y)还是写成原样吧

    [sum_{d=1}^ndsum_{i=1}^{n/d}mu(i)[frac{n}{id}][frac{m}{id}] ]

    是不是(n/d)可以数论分块
    而在计算后面的东西的时候,(frac{n/d}{i})也可以数论分块??
    所以这个时候的复杂度是(O(n))
    与之相对应的就是上面Crash的数字表格(O(n))做法

    可是,像下面那个(O(sqrt n))是怎么做的呢?

    那我们就继续推一步
    我们是不是可以直接对(frac{n}{id})分块呢?
    所以,我们设(T=id)(id)换一下

    [sum_{d=1}^ndsum_{i=1}^{n/d}mu(i)[frac{n}{T}][frac{m}{T}] ]

    这个时候,比较关键的一步
    (T)提出来

    [sum_{T=1}^n[frac{n}{T}][frac{m}{T}]sum_{d|T}dmu(frac{T}{d}) ]

    为什么是这个??
    我们来分析一波
    首先每一个(T)一定对应([frac{n}{T}][frac{m}{T}])
    这一项之和(T)有关,所以可以提出来

    这个时候考虑对于每一个(T),什么样的(i)(d)会给他产生贡献呢?
    最显然的一点,(d)(T)的一个因数
    看到上面的式子,我们不难发现会贡献一个(d)的什么东西
    后面的是什么?(mu(i))
    继续想想,既然(T=id),我们枚举了一个(T)
    又知道(d)(T)的一个因子了,所以(i=frac{T}{d})
    所以,就有了上面把(T)拿出来的式子

    前面的东西看起来可以数论分块
    但是这样子后面的东西怎么办?
    不可能(O(sqrt n))暴力枚举呀

    没错,当然不需要暴力枚举
    我们发现后面的东西也是一个积性函数(因为他是两个积性函数的狄利克雷卷积)
    所以它是可以线性的筛出来的
    到这里,前面对于(T)数论分块
    后面的前缀和可以(O(n))线性筛预处理出来
    此时单次询问整体的复杂度就是(O(sqrt n))

    对了,不要思想江化
    后面那个东西如果不能够直接线性筛
    那就不要线性筛了,
    只要复杂度允许,暴力筛也是很可以的


    其实,如果我们继续观察,很容易知道一点:
    (sum_{d|T}dmu(frac{T}{d})=varphi(T))

    upd:原来底下的证明是假的,已经删掉了,这里用容斥的方法很容易证明,考虑到(mu)是容斥系数就可以很容易的知道上述式子的组合意义。

    我们知道((1*varphi)(i)=i)
    还知道((1*mu)(i)=e)
    其中(1)(f(x)=1)
    (e)(f(x)=[x=1])
    (id)(f(x)=x)

    所以这个东西当然可以线性筛啦。


    莫比乌斯反演差不多就到这里啦
    我们经历的复杂度从(O(n^2))的暴力
    推一步之后变成了(O(n))
    再变成了(O(sqrt n))

    莫比乌斯反演的关键步骤也就是两步
    首先是化简式子,写成莫比乌斯反演的形式
    然后就是怎么处理前缀和,数论分块等东西的问题

    这些能够解决好,莫比乌斯反演的题目就很好解决啦

    Part2线性筛

    当然是怎么各种线性筛东西啦

    线性筛最重要的一点:
    每个数一定,也只会,被他的最小质因子给筛到
    说白点,比如说(72=2*2*2*3*3)
    他就会被他的最小质因子给筛到
    也就是(2*36)时被筛到

    所以,一般线性筛如果要存储其他的东西来筛的话
    一定是记录最小质因子的东西

    大概的写一下几个积性函数:

    (mu)莫比乌斯函数

    这个怎么筛应该都会吧

    (varphi)欧拉函数

    怎么筛应该也很明显吧。

    (d)约数个数

    这个怎么筛?
    考虑唯一分解定理:
    (x=prod p_i^{ai})
    那么(d(x)=prod (ai+1))
    记录一下最小质因子的个数
    每次就先把原来的除掉,再把(+1)后的个数乘上就好啦

    (sigma)约数和

    还是唯一分解定理
    (x=prod p_i^{ai})
    (sigma(x)=prod (sum_{j=0}^{ai}p_i^j))
    记录一下最小质因子的上面那个式子的和
    以及这个因子的(ai)次幂
    每次也是先除掉再乘上新的

    (a^k) (k)次幂

    把这个东西写进来,只是为了提醒一下
    (a^k)这种东西是一个完全积性函数,也是可以丢进去筛的

    (inv)乘法逆元

    没啥,一样的,乘法逆元也是完全积性函数
    蛤,我知道可以(O(n))递推
    只是写一下而已


    我比较懒,不想把板子蒯过来
    直接把ppl的链接给你们嗷(虽然他的代码风格我觉得很丑)

    Part3杜教筛

    来个栗子

    线性筛(O(n))复杂度,美滋滋
    好的,我知道了
    来一个很(interesting)的题目???

    [求sum_{i=1}^nmu(i)的值 ]

    我当然知道你会线性筛
    所以(n<=10^9)

    杜教筛是蛤?

    比如说。。
    我们现在要求一个积性函数(f(i))的前缀和(S(i))
    也就是说(S(n)=sum_{i=1}^nf(i))

    现在很不好算呀
    怎么办??

    这个时候,就来杜教筛套路一波

    我再来找个积性函数(g(i))(不知道是啥)
    (g)(f)做一个卷积

    [(g*f)(i)=sum_{d|i}g(d)f(frac{i}{d}) ]

    再求一下卷积的前缀和

    [sum_{i=1}^n(g*f)(i)=sum_{i=1}^nsum_{d|i}g(d)f(frac{i}{d}) ]

    (d)给提出来

    [sum_{d=1}^ng(d)sum_{d|i}f(frac{i}{d}) ]

    [sum_{d=1}^ng(d)sum_{i=1}^{n/d}f(i) ]

    [sum_{d=1}^ng(d)S(frac{n}{d}) ]

    如果仔细想想
    我们就会有这个式子:

    [g(1)S(n)=sum_{i=1}^ng(i)S(frac{n}{i})-sum_{i=2}^ng(i)S(frac{n}{i}) ]

    前面的东西是狄利克雷卷积

    [g(1)S(n)=sum_{i=1}^n(g*f)(i)-sum_{i=2}^ng(i)S(frac{n}{i}) ]

    如果狄利克雷卷积的前缀和非常好算的话
    那么我们就可以对后面的东西进行数论分块
    然后递归计算。
    提醒一句:
    一定要记忆化,一定要记忆化,一定要记忆化

    回到栗子

    (sum_{i=1}^nmu(i))
    把杜教筛的公式套路式子找过来蛤

    [g(1)S(n)=sum_{i=1}^n(g*mu)(i)-sum_{i=2}^ng(i)S(frac{n}{i}) ]

    看到了(mu)想一个积性函数,让他们的狄利克雷卷积前缀和很好算
    我们知道

    [sum_{d|i}mu(d)=[i=1]=e ]

    也就是说

    [(1*mu)=e ]

    (e)的前缀和是啥?
    当然是(1)
    所以,取(g(x)=1)

    [S(n)=1-sum_{i=2}^nS(frac{n}{i}) ]

    这样子的话,首先线性筛出一部分的(mu)的前缀和
    然后来一波记忆化搜索美滋滋


    再来个栗子把
    把上面的(mu)换成(varphi)
    我们还是知道

    [sum_{d|i}varphi(d)=i=id(i) ]

    所以,如果是(varphi)的话
    就令(g(x)=1)
    所以,

    [S(n)=frac{n*(n+1)}{2}-sum_{i=2}^nS(frac{n}{i}) ]

    多好的套路

    但是,不要被套路给套死啦
    面对不同的函数
    一定要考虑清楚(g)是啥
    好的(g)能让你的程序更加好算

    Part4我也不知道为什么要加上这一部分

    好啦
    上面好好地写了一下莫比乌斯反演和杜教筛
    是不是觉得很简单

    当然,莫比乌斯反演和杜教筛当然可以混在一起

    莫比乌斯反演推柿子
    杜教筛求前缀和
    一点也不矛盾


    既然我也不知道最后这部分干啥
    那就找一堆题目来吧
    欢迎查我水表
    算了
    还是把水表给你们把
    莫比乌斯反演的水表
    杜教筛的水表


    最后,说几句话
    不要因为有了杜教筛和线性筛
    就天天想着怎么筛
    筛不了就滚去写暴力
    埃氏筛法很不错
    暴力枚举因数也很不错

    最后,一句最经典的话作为结尾

    骗分过样例,暴力出奇迹

  • 相关阅读:
    javascript中map的用法
    洛谷P1057传球游戏-题解
    洛谷P1049装箱问题-题解
    洛谷P1048采药-题解
    洛谷P1044栈-题解
    洛谷P1040加分二叉树-题解
    洛谷P1005矩阵取数游戏-题解
    洛谷P1004方格取数-题解
    洛谷P1002过河卒-题解
    搜索
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8305710.html
Copyright © 2011-2022 走看看