zoukankan      html  css  js  c++  java
  • luogu P2303 [SDOi2012]Longge的问题

    传送门

    [sum_{i=1}^{n}gcd(i,n) ]

    考虑枚举所有可能的gcd,可以发现这一定是(n)的约数,当(gcd(i,n)=x)时,(gcd(frac{i}{x},frac{n}{x})=1),可以知道gcd为(x)的数的个数就是(varphi_{frac{n}{x}})

    所以要求的是$$sum_{d|n}d*varphi_{frac{n}{d}}$$

    (varphi)的话只要像筛素数那样筛出来救星了

    #include<bits/stdc++.h>
    #define il inline
    #define re register
    #define LL long long
    #define db double
    #define ldb long double
    #define eps (1e-7)
    
    using namespace std;
    il LL rd()
    {
        LL x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    LL n,prm[20][2],p[10000],tt,tmd,a1;
    void d1(int o,LL s)
    {
      if(o>tt) {p[++tmd]=s;return;}
      for(int i=0;i<=prm[o][1];i++)
        {
          d1(o+1,s);
          s*=prm[o][0];
        }
    }
    int main()
    {
      n=rd();
      LL sn=sqrt(n),bb=n;
      for(LL i=2;i<=sn&&bb;i++)
        {
          if(bb%i==0)
            {
        	  prm[++tt][0]=i;
        	  while(bb%i==0) bb/=i,++prm[tt][1];
            }
        }
      if(bb>1) prm[++tt][0]=bb,prm[tt][1]=1;
      d1(1,1);
      sort(p+1,p+tmd+1);
      map<LL,LL> phi;
      phi[1]=1,tt=0;
      for(LL i=2;i<=tmd;i++)
        {
          if(phi.find(p[i])==phi.end()) phi[p[i]]=p[i]-1,++tt;
          for(int j=1;j<=tt&&p[i]*prm[j][0]<=n;j++)
            {
        	  phi[p[i]*prm[j][0]]=phi[p[i]]*1ll*(prm[j][0]-1);
        	  if(p[i]%prm[j][0]==0) {phi[p[i]*prm[j][0]]+=phi[p[i]];break;}
            }
        }
      for(LL i=1;i<=tmd;i++) a1=(a1+phi[p[i]]*(n/p[i]));
      printf("%lld ",a1);
      return 0;
    }
    
    
  • 相关阅读:
    求24点
    关于参数和返回值的常量性
    点到平面的距离公式
    大端序与小端序
    Quake3中的绝对值函数
    整数超出范围时如何表示?
    关于数组的几道面试题
    在移位数组中查找数
    时间复杂度O(n),空间复杂度O(1)的排序
    C++之对象切割
  • 原文地址:https://www.cnblogs.com/smyjr/p/9775139.html
Copyright © 2011-2022 走看看