zoukankan      html  css  js  c++  java
  • uva11426 gcd、欧拉函数

    题意:给出N,求所有满足i<j<=N的gcd(i,j)之和

    这题去年做过一次。。。

    设f(n)=gcd(1,n)+gcd(2,n)+......+gcd(n-1,n),那么answer=S[N]=f(1)+f(2)+...+f(N)。

    先求出每一个f(n)。

    g(n,i)=【满足gcd(x,n)=i且x<N的x的数量】,i是n的约数

    那么f(n)=sigma【i*g(n,i)】  (i即gcd的值,g(n,i)为数量)

    又注意到gcd(x,n)=i -> gcd(x/i,n/i)=1 -> x/i与n/i互质 -> 满足该条件的x/i有phi(n/i)个

    那么再用欧拉函数就可以求出每一个f(n)啦~

    如果找n的每一个约数i会有点慢,可以枚举i,令n=2*i,3*i,........(n是i的所有倍数且小于MAXN)

    for (int i=1;i<=MX;i++)
      for (int n=i*2;n<=MX;n+=i)
        f[n]=f[n]+(i*phi[n/i]);

    粗体部分的思想很常用,已加入数论模板豪华午餐╮(╯▽╰)╭

     1 #include <stdio.h>
     2 #include <string.h>
     3 //using namespace std;
     4 #define MX 4000005
     5 #define LL long long
     6 
     7 LL phi[MX],f[MX],S[MX];
     8 int N;
     9 
    10 void calc_phi(int n)
    11 {
    12     for (int i=2;i<=n;i++)
    13         phi[i]=0;
    14     phi[1]=1;
    15     for (int i=2;i<=n;i++)
    16         if (!phi[i])
    17             for (int j=i;j<=n;j+=i)
    18             {
    19                 if (!phi[j])    phi[j]=j;
    20                 phi[j]=phi[j]/i*(i-1);
    21             }
    22 }
    23 
    24 int main()
    25 {
    26     calc_phi(MX);
    27 
    28     memset(f,0,sizeof(f));
    29     for (int i=1;i<=MX;i++)
    30         for (int n=i*2;n<=MX;n+=i)
    31             f[n]=f[n]+(i*phi[n/i]);
    32 
    33     S[2]=f[2];
    34     for (int i=3;i<=MX;i++)
    35         S[i]=S[i-1]+f[i];
    36 
    37     while(~scanf("%d",&N))
    38     {
    39         if (N==0)   break;
    40         printf("%lld
    ",S[N]);
    41     }
    42 
    43     return 0;
    44 }
    View Code
  • 相关阅读:
    NXOpen测最最近距离和投影距离
    abp学习日志三(实体&聚合根)
    abp学习日志二(DDD)
    abp学习日记一(安装)
    abp学习日记 初记
    kubernetes学习——minikube入门
    windows10安装Kubernetes和MiniKube
    windows10安装docker desktop(非VMBox)
    Asp.netCore3.0 Docker 阿里云 部署 Demo
    小宝与老财
  • 原文地址:https://www.cnblogs.com/pdev/p/4309339.html
Copyright © 2011-2022 走看看