• 莫比乌斯反演 and 杜教筛总结


    这几天做了几道和杜教筛有关的题目,赶紧记下来怕以后忘了

    首先就是最常用的式子

    对于一个函数f(x)

    设$g(x) =sum_{x|d}f(d)$

    则根据莫比乌斯反演有$$f(x) = sum_{x|d}μ(frac{d}{x})g(d)$$

    举一个最常见的例子

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

    令$$g(x) =sum_{i=1}^{N}sum_{j=1}^{M} [x | gcd(i, j)]$$

    根据上面的公式有$$f(x) = sum_{x | d}μ(frac{d}{x})g(d)$$

    因为$$g(x) =sum_{i=1}^{[frac{N}{x}]}sum_{j=1}^{[frac{M}{x}]} [gcd(i, j) == 1]$$可以O(1)求出

    答案即为f(1)

     但有些时候n很大,这时候O(n)的时间复杂度是不可接受的,我们就需要用杜教筛来处理一些问题

    比如$$sum_{i=1}^{N}μ(i)$$

    μ有一个性质:$$sum_{d|n}mu(d)=[n=1]$$

    于是就有$$sum_{i=1}^{N}sum_{d|i}μ(d) = 1$$

    变换一下枚举倍数$$sum_{d=1}^{N}sum_{j = 1}^{[frac{N}{d}]}μ(j) = 1$$

    于是 $$sum_{i=1}^{N}μ(i) = 1 - sum_{d=2}^{N}sum_{j = 1}^{[frac{N}{d}]}μ(j)$$

    这个式子就可以递归求解了

    我们预处理出前1e6的μ的前缀和, 每个$[frac{N}{d}]$都是一个区间,可以一起求出

    求前缀和递归函数:

     1 int sieve(LL x)
     2 {
     3     if(x <= MAXN) {
     4         return sum[x];
     5     }
     6     if(m[x]) {
     7         return m[x];
     8     }
     9     int S = 1;
    10     for(LL i = 2, j; i <= x; i = j + 1) {
    11         j = x / (x / i);
    12         S = (S - (LL)(j - i + 1) * sieve(x / i) % MOD + MOD) % MOD;
    13     }
    14     return m[x] = S;
    15 }
    View Code

    如果要求$$sum_{i=1}^{N}i*μ(i) $$也可以用同样的方法

    根据性质有$$sum_{i=1}^{N}isum_{d|i}μ(d) = 1$$

    则$$sum_{i=1}^{N}sum_{d|i}μ(d)*d*frac{i}{d} = 1$$

    同样枚举倍数$$sum_{d=1}^{N}dsum_{j=1}^{[frac{N}{d}]}μ(j)*j = 1$$

    则$$sum_{i=1}^{N}i*μ(i)=1 - sum_{d=2}^{N}dsum_{i=1}^{[frac{N}{d}]}μ(i)*i $$

    做法就与之前相同了

    递归函数:

     1 inline LL sieve(LL x)
     2 {
     3     if(x <= 5e6) {
     4         return sum[x];
     5     }
     6     int hh = get_h(x);
     7     if(ha[hh] == x) {
     8         return h[hh];
     9     }
    10     ha[hh] = x;
    11     h[hh] = 1;
    12     LL i = 2;
    13     while(i <= x)
    14     {
    15         LL m = x / i, j = x / m;
    16         h[hh] = ((LL)h[hh] - (i + j) % MOD * (( j - i + 1) % MOD) % MOD * rev2 % MOD * sieve(m) % MOD + MOD) % MOD;
    17         i = j + 1;
    18     }
    19     return h[hh];
    20 }
    View Code
  • 相关阅读:
    快速幂取模
    程序人生系列之新闻发布系统 0105
    JavaWeb之博客系统(四)
    [转]树状数组
    题目:免费午餐
    题目:删数问题
    题目:三元组
    题目:分子团
    题目:[汪老师结婚]婚礼上的袭击
    题目:[SBN号码]
  • 原文地址:https://www.cnblogs.com/wuenze/p/9180232.html
Copyright © 2020-2023  润新知