• 莫比乌斯函数总结


    莫比乌斯函数总结

    性质(sum_{d|n}mu(d)=[n==1])
    这个可以用组合数的性质来证,形象点的话就是杨辉三角。
    因为恒等式:(sum_{i=0}^{n}(-1)^nC_{n}^{i}=0).

    莫比乌斯反演:
    形式一:
    已知:(g(n)=sum_{d|n}f(d)),则有:(f(n)=sum_{d|n}mu(d)g(frac{n}{d})).
    证明如下:

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

    交换求和次序,有:

    [egin{aligned} &sum_{d|n}mu(d)sum_{k|frac{n}{d}}f(k)\ =&sum_{k|n}f(k)sum_{d|frac{n}{k}}mu(d)\ =&sum_{k|n}f(k)[frac{n}{k}=1]=f(n) end{aligned} ]

    故得证.
    形式二:
    已知:(g(n)=sum_{n|d}f(d)),则有:(f(n)=sum_{n|d}mu(frac{d}{n})g(d)).
    证明如下:
    (k=frac{d}{n}),则有:

    [egin{aligned} &sum_{n|d}mu(frac{d}{n})g(d)\ =&sum_{k=1}^{infty}mu(k)g(nk)\ =&sum_{k=1}^{infty}mu(k)sum_{nk|t}f(t) end{aligned} ]

    交换求和次序,有:

    [egin{aligned} &sum_{k=1}^{infty}mu(k)sum_{nk|t}f(t)\ =&sum_{n|t}f(t)sum_{k|frac{t}{n}}mu(k)\ =&sum_{n|t}f(t)[frac{t}{n}=1]=f(n) end{aligned} ]

    故得证.

    常用技巧(应用):
    一个性质:

    [lfloorfrac{lfloorfrac{x}{a} floor}{b} floor=lfloorfrac{x}{ab} floor ]

    证明如下:
    (y=lfloorfrac{x}{a} floor,z=lfloorfrac{x}{ab} floor),显然有:(x=zab+c,cleq ab).
    等式两边同时除以(a)并向下取整有:(y=zb+lfloorfrac{c}{a} floor).
    再同时除以(b)并向下取整:(lfloorfrac{lfloorfrac{x}{a} floor}{b} floor=z+lfloorfrac{lfloorfrac{c}{a} floor}{b} floor).
    之后就比较显然了。

    整除分块:
    整除分块经常在相关数论问题中用到,主要是用来解决下列求和式:

    [sum_{i=1}^{n}lfloorfrac{n}{i} floor ]

    证明我就不写了,就说点有用的性质吧:

    • 对于(1leq ileq n)(lfloorfrac{n}{i} floor)只有至多(2sqrt{n})个不同取值。
    • 对于任一(x),当(xleq ileq lfloorfrac{n}{lfloorfrac{n}{x} floor} floor)时,(lfloorfrac{n}{i} floor)的值都相等。

    有了上面两个性质,那么可以加速求和式,复杂度为(sqrt{n})

    例一:
    求:(sum_{i=1}^{n}sum_{j=1}^{m}[gcd(i,j)=1]).

    [egin{aligned} &sum_{i=1}^{n}sum_{j=1}^{m}[gcd(i,j)=1]\ =&sum_{i=1}^{n}sum_{j=1}^{m}sum_{d|gcd(i,j)}mu(d)\ =&sum_{i=1}^{n}sum_{j=1}^{m}sum_{d|i,d|j}mu(d) end{aligned} ]

    说明一下:从第一步到第二步多出来一个和式,就相当于一个容斥的过程,考虑所有的((i,j)),对于他们的(gcd)来进行容斥:先加上所有的情况,然后减去(gcd)(2,3,5...)倍数的情况,但会多减,所以加回来。
    之后再进行变换得:

    [egin{aligned} &sum_{d}mu(d)sum_{i=1}^{n}sum_{d|i}sum_{j=1}^{m}sum_{d|j}\ =&sum_{d}mu(d)lfloorfrac{n}{d} floorlfloorfrac{m}{d} floor end{aligned} ]

    后面的部分直接整除分块,然后预处理(mu)的前缀和就行了。

    例二:
    求:(sum_{i=1}^{n}sum_{j=1}^{m}gcd(i,j))

    这个和第一个比较类似,我们变化一下就有:

    [egin{aligned} &sum{d}sum_{i=1}^{n}sum_{j=1}^{m}[gcd(i,j)=d]\ =&sum{d}sum_{i=1}^{frac{n}{d}}sum_{j=1}^{frac{m}{d}}[gcd(i,j)=1] end{aligned} ]

    根据例一得:

    [egin{aligned} &sum{d}sum_{i=1}^{frac{n}{d}}sum_{j=1}^{frac{m}{d}}[gcd(i,j)=1]\ =&sum{d}sum_tmu(t)lfloorfrac{n}{dt} floorlfloorfrac{m}{dt} floor end{aligned} ]

    (T=dt),则上式可化为:

    [egin{aligned} =&sum{frac{T}{t}}sum_{t}mu(frac{T}{d})lfloorfrac{n}{T} floorlfloorfrac{m}{T} floor\ =&sum_{T}lfloorfrac{n}{T} floorlfloorfrac{m}{T} floorsum_{t|T}mu(t)frac{T}{t}\ =&sum_Tlfloorfrac{n}{T} floorlfloorfrac{m}{T} floorvarphi(T) end{aligned} ]

    说说为什么最后转化为了欧拉函数:
    欧拉函数有个十分有用的性质:(sum_{d|n}varphi(d)=n),证明的话主要从(f(n)=sum_{d|n}varphi(d))这个函数为积性函数入手。同时还有两个个性质也比较有用:一个是(varphi(p^m)=p^m-p^{m-1}),另一个是小于(n)的数中,与(n)互质的数的和为(frac{nvarphi(n)}{2},n>1),为什么呢?因为有(gcd(m,n)=gcd(n,n-m),所以是成对的~)
    回到正题,有了这个式子反演一下就有:

    [varphi(n)=sum_{d|n}mu(d)frac{n}{d} ]

    对于例二,整除分块+预处理欧拉函数就行了。

    相关例题:
    洛谷P1829

    题意:
    (sum_{i=1}^nsum_{j=1}^m lcm(i,j))

    思路:
    推导过程如下:

    [egin{aligned} &sum_{i=1}^n sum_{j=1}^m lcm(i,j)\ =&sum_{i=1}^n sum_{j=1}^m frac{ij}{gcd(i,j)}\ =&sum_dsum_isum_jfrac{ij}{d}(gcd(i,j)=d)\ =&sum_dsum_{i=1}^{lfloorfrac{n}{d} floor}sum_{j=1}^{lfloorfrac{m}{d} floor}ijd(gcd(i,j)=1)\ =&sum_ddsum_{i=1}^{lfloorfrac{n}{d} floor}sum_{j=1}^{lfloorfrac{m}{d} floor}ij(gcd(i,j)=1) end{aligned} ]

    后面部分是不是很熟悉,我们先求(sum(n,m)=sum_isum_jij(gcd(i,j)=1)).
    按照套路,有:

    [egin{aligned} sum(n,m)=&sum_isum_jijsum_{d|gcd(i,j)}mu(d)\ =&sum_d d^2mu(d)sum_{i=1}^{lfloorfrac{n}{d} floor}sum_{j=1}^{lfloorfrac{m}{d} floor}ij end{aligned} ]

    后面部分为两个等差数列求和,显然可以直接数论分块来搞。
    回到原式:

    [sum_d dcdot sum(lfloorfrac{n}{d}, frac{m}{d} floor) ]

    发现这后面也可以数论分块搞,所以就是分块套分块,总复杂度为(O(n))

    Code
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 1e7 + 5, MOD = 20101009;
    int n, m;
    int mu[N], p[N], sum[N];
    bool chk[N];
    void init() {
        mu[1] = 1;
        int cnt = 0, k = min(n, m);
        for(int i = 2; i <= k; i++) {
            if(!chk[i]) p[++cnt] = i, mu[i] = -1;
            for(int j = 1; j <= cnt && i * p[j] <= k; j++) {
                chk[i * p[j]] = 1;
                if(i % p[j] == 0) {mu[i * p[j]] = 0; break;}
                mu[i * p[j]] = -mu[i];
            }
        }
        for(int i = 1; i <= k; i++) sum[i] = ((sum[i - 1] + 1ll * mu[i] * i * i % MOD) % MOD + MOD) % MOD;
    }
    int Sum(int x) {
        return 1ll * x * (x + 1) / 2 % MOD;
    }
    int calc(int n, int m) {
        int ans = 0;
        for(int i = 1, j; i <= min(n, m); i = j + 1) {
            j = min(n / (n / i), m / (m / i));
            ans = (ans + 1ll * (sum[j] - sum[i - 1] + MOD) * Sum(n / i) % MOD * Sum(m / i) % MOD) % MOD;
        }
        return ans;
    }
    int solve(int n, int m) {
        int ans = 0;
        for(int i = 1, j; i <= min(n, m); i = j + 1) {
            j = min(n / (n / i), m / (m / i));
            ans = (ans + 1ll * (i + j) * (j - i + 1) / 2 % MOD * calc(n / i, m / i) % MOD) % MOD;
        }
        return ans;
    }
    int main() {
    #ifdef heyuhhh
        freopen("input.in", "r", stdin);
    #else
        ios::sync_with_stdio(false); cin.tie(0);
    #endif
        cin >> n >> m;
        init();
        cout << solve(n, m);
        return 0;
    }
    
    
  • 相关阅读:
    在Win10中通过命令行打开UWP应用
    前端学习Docker
    Puppeteer的使用
    taro教程
    22种开源Vue模板和主题框架「干货」
    36种免费React模板和主题「干货」
    移动端1px显示异常解决方案
    前端性能优化(二)
    Vue.set()和this.$set()源码解析
    2018年8月7日 乐视2 X621 刷机包下载链接
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/11231502.html
Copyright © 2020-2023  润新知