• [ACM-ICPC 2018 徐州赛区网络预赛][D. Easy Math]


    题目链接:Easy Math

    题目大意:给定(n(1leqslant nleqslant 10^{12}),m(1leqslant mleqslant 2*10^{9})),求(sum_{i=1}^{m}mu (icdot n))。

    题解:废话少说,直接上公式

    $$mu(icdot n)=left{egin{matrix}
    mu(i)cdotmu(n) & gcd(i,n)==1\
    0 & other
    end{matrix} ight.$$

    $$F(n,m)=sum_{i=1}^{m}mu(icdot n)$$

    则有$$F(n,m)=mu(n)cdotsum_{i=1}^{m}mu (i)cdot[gcd(i,n)==1]$$

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

    $$F(n,m)=mu(n)cdotsum_{i=1}^{m}mu (i)sum_{d|gcd(i,n)}^{ }mu(d)$$

    $$F(n,m)=mu(n)cdotsum_{d|n}^{dleqslant m}mu(d)cdotsum_{i=1}^{left lfloor frac{m}{d} ight floor}mu(icdot d)$$

    $$F(n,m)=mu(n)cdotsum_{d|n}^{dleqslant m}mu(d)cdot F(d,left lfloor frac{m}{d} ight floor)$$

    推出式子后,递归求解即可,当n==1时,有(F(n,m)=M(m)=sum_{i=1}^{m}mu(i)),关于这个式子有一个莫比乌斯反演的经典公式,就是$$M(n)=1-sum_{i=2}^{n}M(left lfloor frac{n}{i} ight floor)$$预处理出莫比乌斯函数及其前缀和的值后即可,求M(n)的时候记得要分块做

    #include<bits/stdc++.h>
    using namespace std;
    #define N 10000001
    #define LL long long
    LL n,m,cnt,p[N],f[N],s[N];
    map<LL,LL>M;
    bool x[N];
    void pretype()
    {
        f[1]=1;
        for(int i=2;i<N;i++)
          {
          if(!x[i])p[++cnt]=i,f[i]=-1;
          for(int j=1;j<=cnt && i*p[j]<N;j++)
            {
            f[i*p[j]]=-f[i];
            x[i*p[j]]=true;
            if(i%p[j]==0){f[i*p[j]]=0;break;}
            }
          }
        for(int i=1;i<N;i++)
          s[i]=s[i-1]+f[i];
    }
    LL get(LL n)
    {
        if(n<N)return f[n];
        LL k=1;
        for(LL i=2;i*i<=n;i++)
          if(n%i==0)
            {
            if(n%(i*i)==0)return 0;
            k*=-1,n/=i;
            }
        if(n>1)k*=-1;return k;
    }
    LL get_M(LL n)
    {
        if(n<N)return s[n];
        if(M[n])return M[n];
        LL res=1,nxt;
        for(LL i=2;i<=n;i=nxt+1)
          {
          nxt=min(n,n/(n/i));
          res-=(nxt-i+1)*get_M(n/i);
          }
        return M[n]=res;
    }
    LL F(LL n,LL m)
    {
        if(n==1)return get_M(m);
        LL miu=get(n),res=0;
        if(miu==0)return 0;
        for(LL d=1;d*d<=n && d<=m;d++)if(n%d==0)
          {
          res+=get(d)*F(d,m/d);
          if(n/d<=m)res+=get(n/d)*F(n/d,m/(n/d));
          }
        return miu*res;
    }
    int main()
    {
        pretype();
        scanf("%lld%lld",&m,&n);
        printf("%lld
    ",F(n,m));
    }
    View Code
  • 相关阅读:
    Google 开源的 Python 命令行库:深入 fire(二)
    开启 Django 博客的 RSS 功能
    MongoDB 分片键的选择与案例
    Log4Net写入到数据库配置过程中的一些小问题备忘
    《WCF服务编程第三版》知识点摘录
    Android调用基于.net的WebService
    心跳包实现的另一种机制
    无法加载一个或多个请求的类型。有关更多信息,请检索 LoaderExceptions 属性。
    解决SaveChanges会Hold住之前的错误的问题
    memcached工作原理与优化建议
  • 原文地址:https://www.cnblogs.com/DeaphetS/p/9614591.html
Copyright © 2020-2023  润新知