• 莫比乌斯反演的一些简单应用#1


    莫比乌斯反演的式子我们在之前已经推导出来了为:

    (f(n)=sum_{d|n}g(d),g(n)=sum_{d|n}f(d) imesmu(frac n d))

    具体的推导过程可以参考我之前的一篇博客

    而我们在推导莫比乌斯反演这个式子之前,曾得到另外一个同样也很重要的式子:

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

    也就是 (mu*1=epsilon)

    这个式子有啥用呢?

    我们把它稍稍转换一下,令 (n=gcd(i,j)),这样的话,式子就变成了:

    (sum_{d|gcd(i,j)}mu(d)=[gcd(i,j)=1])

    而我们可以通过交换 (Sigma) 的位置来实现对一些类似 (gcd(i,j)=1) 式子的求解。

    例1:

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

    这个就是我上面说的式子的一个具体应用啦,有了上面的式子,这个问题还是很简单的啦。

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

    (=sum_{i=1}^nsum_{i=1}^msum_{d|gcd(i,j)}mu(d))

    (=sum_{d=1}^nmu(d)sum_{i=1}^{lfloorfrac n d floor}sum_{j=1}^{lfloorfrac m d floor})

    (=sum_{d=1}^nmu(d) imeslfloorfrac n d floor imeslfloorfrac m d floor)

    然后就可以在(O(sqrt{n})) 的时间内求解了。

    因为是例1,所以还是贴个代码,当个示范:

    #include<bits/stdc++.h>
    #define ll long long
    const int N=10000000;
    int mu[N+5],vis[N+5],sum[N+5],p[N+5];
    ll ans;
    int n,m,q;
    using namespace std;
    void sieve(){
        mu[1]=vis[1]=1;
        for(int i=2;i<=N;i++){
            if (!vis[i]) p[++p[0]]=i,mu[i]=-1;
            for (int j=1;j<=p[0]&&i*p[j]<=N;j++){
                vis[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<=N;i++)
            mu[i]+=mu[i-1];
    }
    int main(){
        sieve();
        scanf("%d",&q);
        while (q--){
            scanf("%d%d",&n,&m);
            if (n>m) swap(n,m);
            ans=0;
            for (int l=1,r;l<=n;l=r+1){
                r=min(n/(n/l),m/(m/l));
                ans+=1ll*(mu[r]-mu[l-1])*(n/l)*(m/l);
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    

    例2:

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

    其实这里只需要一个很简单的转化:

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

    (=sum_{i=1}^{lfloorfrac n k floor}sum_{j=1}^{lfloorfrac m k floor}[gcd(i,j)=1])

    然后就和上面一样啦。

    例3:

    求:(sum_{i=1}^nsum_{j=1}^mi imes j imes[gcd(i,j)=k])

    这个和上面其实也没有什么大差别,这里的(i,j)其实只是一个副产品,只要我们移(Sigma)的时候不要忘记对(i,j)项产生的影响即可。

    ( sum_{i=1}^nsum_{j=1}^mi imes j imes[gcd(i,j)=k])

    (=sum_{i=1}^{lfloorfrac n k floor}sum_{j=1}^{lfloorfrac m k floor}i imes j imes k^2 imes[gcd(i,j)=1])

    (=k^2 imessum_{d=1}^{lfloorfrac n k floor}mu(d) imessum_{i=1}^{lfloorfrac n {kd} floor}i imessum_{j=1}^{lfloorfrac m {kd} floor}j)

    (sum[n]=sum_{i=1}^ni)

    (=k^2 imessum_{d=1}^{lfloorfrac n k floor}d^2 imesmu(d) imes sum[lfloorfrac n {kd} floor] imes sum[lfloorfrac m {kd} floor])

    (O(sqrt{n})) 求解即可。

    好了,先就这么多吧,剩下还有很多,毕竟莫比乌斯反演博大精深,以后再写了。

  • 相关阅读:
    说一说javascript的异步编程
    Flink 整合 Nacos,让 Flink 作业配置动态更新不再是难事
    Flink 整合 Apollo,动态更新 Flink 作业配置
    一文让你彻底了解大数据实时计算引擎 Flink
    《大数据实时计算引擎 Flink 实战与性能优化》新专栏
    滴滴实时计算发展之路及平台架构实践
    Flink 从 0 到 1 学习 —— Flink Data transformation(转换)
    Flink Connector 深度解析
    Flink 从 0 到 1 学习 —— Flink 配置文件详解
    vue-cli3如何配置 eslint 及配合 vscode 自动保存
  • 原文地址:https://www.cnblogs.com/WR-Eternity/p/10990125.html
Copyright © 2020-2023  润新知