• bzoj 3944 杜教筛


    题目中要求phi和miu的前缀和,利用杜教筛可以推出公式。我们令

    那么有公式

    类比欧拉函数,我们可以推出莫比乌斯函数的和公式为  (公式证明懒得写了,主要核心是利用Dirichlet卷积的性质 phi * 1 =id, mu * 1 =0(n>1) 然后利用神奇的杜教筛搞一搞 )

    因为有一个n=1的特例,所以这里有一个1,我一开始错在这里,总和答案差1........

    所以我们可以预处理一波phi和mu的前缀和 然后递归的处理,用map记忆一下就可以了,复杂度为n的三分之二次幂(我不会证明)——by VANE

    #include<bits/stdc++.h>
    using namespace std;
    const int M=5e6;
    bool not_prim[M+1];
    typedef long long ll;
    int prim[M>>1],prim_tot;
    ll mu[M+1],phi[M+1];
    map<int,ll> _phi,_mu;
    void pre()
    {
        mu[1]=1;not_prim[1]=1;
        phi[1]=1;
        for(int i=2;i<=M;++i)
        {
            if(!not_prim[i])
            {
                prim[++prim_tot]=i;
                phi[i]=i-1;
                mu[i]=-1;
            }
            for(int j=1;j<=prim_tot&&prim[j]<=M/i;++j)
            {
                not_prim[prim[j]*i]=1;
                if(i%prim[j]==0)
                {
                    phi[prim[j]*i]=phi[i]*prim[j];
                    mu[prim[j]*i]=0;
                    break;
                }
                phi[prim[j]*i]=phi[i]*phi[prim[j]];
                mu[prim[j]*i]=-mu[i];
            }
        }
        for(int i=1;i<=M;++i)
        {
            phi[i]+=phi[i-1];
            mu[i]+=mu[i-1];
        }
    }
    ll calcphi(ll n)
    {
        if(n<=M) return phi[n];
        map<int,ll>::iterator it;
        if((it=_phi.find(n))!=_phi.end())
        return _phi[n];
        ll i,last;ll res=1ll*n*(n+1)/2;
        for(i=2;i<=n;i=last+1)
        {
            last=n/(n/i);
            res-=(last-i+1)*calcphi(n/i);
        }
        return _phi[n]=res;
    }
    ll calcmu(ll n)
    {
        if(n<=M) return mu[n];
        map<int,ll>::iterator it;
        if((it=_mu.find(n))!=_mu.end()) return _mu[n];
        ll i,last;ll res=1;
        for(i=2;i<=n;i=last+1)
        {
            last=n/(n/i);
            res-=(last-i+1)*calcmu(n/i);
         } 
         return _mu[n]=res;
    }
    int main()
    {
        pre();
        int t;
        scanf("%d",&t);
        while(t--)
        {
            ll n;
            scanf("%lld",&n);
            printf("%lld %lld
    ",calcphi(n),calcmu(n));
        } 
    }
  • 相关阅读:
    HTML DOM item() 方法
    php输出年份
    CSS中如何选择ul下li的奇数、偶数行
    对象的继承
    this指向
    如何安装Firebug
    JSON数据格式
    PHP: configure: error: mysql configure failed. Please check config.log for more information.
    linux下挂载iso镜像文件(转)
    Linux 下mysql修改数据库存放目录方法和可能遇到的问题
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8059799.html
Copyright © 2020-2023  润新知