• UVA 11426 GCD


    Given the value of N, you will have to find the value of G. The definition of G is given below:
    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<N;i++)
    for(j=i+1;j<=N;j++)
    {
    G+=gcd(i,j);
    }(i < j)
    /*Here gcd() is a function that finds
    the greatest common divisor of the two
    input numbers*/
    Input


    The input file contains at most 100 lines of inputs. Each line contains an integer N (1 < N < 4000001).
    The meaning of N is given in the problem statement. Input is terminated by a line containing a single
    zero.


    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

    Sample Output

    67

    13015

    143295493160

    题目大意:就是求G[n]
     
    G[n] = gcd(1,2) + gcd(1,3) + ... + gcd(1,n-1) + gcd(1,n)
             +gcd(2,3) + gcd(2,4) + ... + gcd(2,n-1) + gcd(2,n)
             +...
             +gcd(n-2,n)+ gcd(n-1,n);
     
    这样我们可以得到一个规律:
     
    G[n] = G[n - 1] + b[n]( 其中b[n]就是上面红色部分的和b[n] = gcd(1,n) + gcd(2,n) + ... + gcd(n-1,n)  )
     
    b[n] = gcd(1,n) + gcd(2,n) + ... + gcd(n-1,n) 
    b[n]的加数我们可以统另为gcd(b, n);
     
    设a[xi] 表示使gcd(b,n) = xi成立的b的个数
    那么b[n] = a[xi]*xi = a[x1]*x1 + a[x2]*x2 + a[x3]*x3 +...+a[xs]*xs
    我们就要求a[xi]
     
    gcd(b,n) = xi可以转化为求有多少个b/xi使gcd(b/xi,n/xi)=xi/xi = 1,要求b/xi的个数就相当于求与n/xi互质的数有多少个(即求n/xi的欧拉函数)因为只有互质的两个数气最大公约数才是1
    那么我们最终求得就是b[n] = a[n/xi] *1 * xi (i = 1,2,3,...)
     
     
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<stdlib.h>
    #include<algorithm>
    
    using namespace std;
    
    const int N = 4000010;
    typedef long long ll;
    
    ll a[N], b[N], G[N];
    
    int main()
    {
        ll n;
        for(ll i = 0 ; i < N ; i++)
            a[i] = i;//初始化
        a[1] = 1;
        for(ll i = 2 ; i < N ; i++)
        {
            if(a[i] == i)
            {
                a[i] -= a[i] / i;
                for(ll j = i * 2 ; j < N ; j += i)
                    a[j] -= a[j] / i;
            }
        }//欧拉函数打表
        for(ll i = 1 ; i < N ; i++)
        {
            for(ll j = i * 2 ; j < N ; j += i)
                b[j] += a[j / i] * i;
        }//b[n]打表(这里b的下标应含因子i)
        G[2] = 1;
        for(ll i = 3 ; i < N ; i++)
            G[i] = G[i - 1] + b[i];//G[n]打表
        while(scanf("%lld", &n), n)
        {
            printf("%lld
    ", G[n]);
        }
        return 0;
    }
     
     
  • 相关阅读:
    appium知识01-环境设置
    移动端测试基础知识02
    魔术方法和反射
    面向对象开发: 封装, 继承, 多态
    正则的用法
    内置方法, 第三方模块(math, random, pickle, json, time, os, shutil, zip, tarfile), 导入包
    推导式(列表, 集合, 字典), 生成器
    迭代器, 高阶函数(map, filter, reduce, sorted) , 递归函数
    函数globals和locals用法, LEGB原则, 闭包函数 , 匿名函数
    字符串, 列表, 元祖, 集合, 字典的相关操作和函数, 深浅copy
  • 原文地址:https://www.cnblogs.com/qq2424260747/p/4952923.html
Copyright © 2020-2023  润新知