zoukankan      html  css  js  c++  java
  • UVa11426

    GCD Extreme (II)

    Given the value of N, you will have to find the value of G. The definition of G is given below:

    uva 11426 - GCD - Extreme (II)" v:shapes="_x0000_i1025">

    Here GCD(i,j) means the greatest common divisor of integer i and integer j.

    For those who have trouble understanding summation notation, the meaning of G is given in the following code:

    G=0;

    for(i=1;i<<span class="SpellE">N;i++)

    for(j=i+1;j<=N;j++)

    {

        G+=gcd(i,j);

    }

    Input

    The input file contains at most 100 lines of inputs. Each line contains an integer N (1 

     

    Output

    For each line of input produce one line of output. This line contains the value of G for the corresponding N. The value of G will fit in a 64-bit signed integer.

    Sample Input 

    10

    100

    200000

    0

     

    Output for Sample Input

    67

    13015

    143295493160

    题意:
           输入正整数n,求gcd(1,2)+gcd(1,3)+gcd(2,3)+…+gcd(n-1,n),即所有满足1<=i<j<=n的数对(i,j)所对应的gcd(i,j)之和。

    分析:

           设f(n) = gcd(1,n)+gcd(2,n)+…+gcd(n-1,n),则所求答案就是S(n)=f(2)+f(3)+…f(n)。

    只要求出f(n),就可以得到答案S(n) = S(n-1)+f(n)。

           注意到所有的gcd(x,n)都是n的约数,可以按照这个约数进行分类,用g(n,i)表示满足gcd(x,n)=i的不大于n的正整数x的个数,则f(n)=sum{i*g(n,i)|i是n的约数}。注意到gcd(x,n)=i的充要条件是gcd(x/I,n/i)=1,所以g(n,i)=phi(n/i)。

           我们不需要对每一个n都枚举其约数i。可以反过来思考,对于每一个i,枚举其倍数n并更新f(n)的值那么时间复杂度将与筛法同阶。

     1 #include <cstdio>
     2 #include <cstring>
     3 const int maxn = 4000000;
     4 typedef long long LL;
     5 LL S[maxn + 1],f[maxn + 1];
     6 int phi[maxn];
     7 void phi_table(int n){
     8     for(int i = 2 ; i <= n ; i++) phi[i] = 0;
     9     phi[1] = 1;
    10     for(int i = 2; i <= n ; i++) if(!phi[i])
    11         for(int j = i ; j <= n ; j += i){
    12             if(!phi[j]) phi[j] = j;
    13             phi[j] = phi[j] / i * (i - 1);
    14         }
    15 }
    16 int main(){
    17     phi_table(maxn);
    18     // 预处理f
    19     memset(f,0,sizeof f);
    20     for(int i = 1 ; i <= maxn ; i++)
    21         for(int n = i * 2 ; n <= maxn ; n += i) f[n] += i * phi[n / i];
    22     // 预处理S
    23     S[2] = f[2];
    24     for(int n = 3 ; n <= maxn ; n++) S[n] = S[n - 1] + f[n];
    25     int n;
    26     while(scanf("%d",&n) == 1 && n)
    27         printf("%lld
    ",S[n]);
    28     return 0;
    29 }
    View Code
  • 相关阅读:
    vue keep-alive的使用
    vscode 快捷键整理
    form表单的验证validator如何传递参数
    使用elementui 的validateField,resetFields,clearValidate的使用
    vue sass样式穿透实现
    部署node服务(在本地模拟环境进行部署)
    利用存css实现弧形边界
    koa mongoose 实践篇,各种必要的功能总结;
    koa mogoose 创建后台服务连接数据库并进行增删改查
    vue项目中 render函数直接操作html元素报错
  • 原文地址:https://www.cnblogs.com/cyb123456/p/5806977.html
Copyright © 2011-2022 走看看