zoukankan      html  css  js  c++  java
  • UVA 11426

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

    i=1
    j

    ≤N
    j=i+1
    GCD(i, j)
    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);
    }
    /*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

    题意:给出n,求∑(i!=j)   gcd(i,j)   (1<=i,j<=n)

    题解:s(n)=s(n-1)+gcd(1,n)+gcd(2,n)+……+gcd(n-1,n);

    设f(n)=gcd(1,n)+gcd(2,n)+……+gcd(n-1,n)。

    gcd(x,n)=i是n的约数(x<n),按照这个约数进行分类。设满足gcd(x,n)=i的约束有g(n,i)个,则有f(n)=sum(i*g(n,i))。

    而gcd(x,n)=i等价于gcd(x/i,n/i)=1,因此g(n,i)等价于phi(n/i).phi(x)为欧拉函数。

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    using namespace std ;
    typedef long long ll;
    
    const int N=4000000+10;
    
    ll phi[N+5] , f[N+5];
    void phi_table() {
      for(int i = 2;i <= N; i++) phi[i] = 0;
      phi[1] = 1;
      for(int i = 2; i <= N; i++) {
        if(!phi[i]) {
            for(int j = i; j <= N; j += i) {
                if(!phi[j]) phi[j] = j;
                phi[j] = phi[j] / i * (i-1);
            }
        }
      }
    }
    ll s[N+5],n;
    int main() {
        phi_table();
        for(int i = 1; i <= N; i++) {
            for(int j = i + i; j <= N; j += i) {
                f[j] += i * phi[j / i];
            }
        }
        for(int i = 1; i <= N; i++) s[i] = s[i-1] + f[i];
        while(~scanf("%lld",&n)) {
            if(!n) break;
            printf("%lld
    ", s[n]);
        }
        return 0;
    }
    代码
  • 相关阅读:
    静态成员在类中的初始化
    博客中尖括号不显示的问题
    声明vector对象保存函数指针
    返回数组指针的函数
    C++ 指针与引用的差别
    Configure Eclipse “Content Assist”
    How to install Eclipse-Color-Theme
    国内 git 托管平台
    SHA1 对文件求信息摘要的实现
    SHA1 对字符串求摘要的实现
  • 原文地址:https://www.cnblogs.com/zxhl/p/5107989.html
Copyright © 2011-2022 走看看