zoukankan      html  css  js  c++  java
  • uva 11426 线性欧拉函数筛选+递推

    Problem J GCD Extreme (II)

    Input: Standard Input

    Output: Standard Output

    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);

    }

    /*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

    Output for Sample Input

    67

    13015

    143295493160

    /*
    题目大意给出一个n,求sum(gcd(i,j),0<i<j<=n);
    可以明显的看出来s[n]=s[n-1]+f[n];
    f[n]=sum(gcd(i,n),0<i<n);
    现在麻烦的是求f[n]
    gcd(x,n)的值都是n的约数,则f[n]=
    sum{i*g(n,i),i是n的约数},注意到gcd(x,n)=i的
    充要条件是gcd(x/i,n/i)=1,因此满足条件的
    x/i有phi(n/i)个,说明gcd(n,i)=phi(n/i).
    f[n]=sum{i*phi(n/i),1=<i<n}
    因此可以搞个for循环对i循环,只要i<n,f[n]+=i*phi(n/i);
    */
    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define Max 4000000
    
    __int64 s[Max+5],f[Max+5],phi[Max+5];
    int prime[Max/10];
    bool flag[Max+5];
    
    void Init()
    {
        int i,j,num=0;
        memset(flag,1,sizeof(flag));
        phi[1]=1;
        for(i=2;i<=Max;i++)//欧拉筛选
        {
            if(flag[i])
            {
                prime[num++]=i;
                phi[i]=i-1;
            }
            for(j=0;j<num && prime[j]*i<=Max;j++)
            {
                flag[i*prime[j]]=false;
                if(i%prime[j]==0)
                {
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
                else phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
        }
        memset(f,0,sizeof(f));
        for(i=1;i<=Max;i++)//f[n]更新
        {
            //因为f[n]=gcd[1,n]+....+gcd[n-1,n]所以j=2*i开始,若从j=i开始那就等同于加上了一项gcd(n,n)
            for(j=2*i;j<=Max;j+=i)
                f[j]+=i*phi[j/i];
        }
        memset(s,0,sizeof(s));
        for(i=2;i<=Max;i++)
            s[i]=s[i-1]+f[i];
    }
    
    int main()
    {
        Init();
        int n;
        while(cin>>n,n)
            printf("%I64d
    ",s[n]);
        return 0;
    }
     
     
  • 相关阅读:
    Python
    Python
    Python
    Python
    Python
    Python
    Python
    python
    对象
    py常用模块
  • 原文地址:https://www.cnblogs.com/xiong-/p/3216539.html
Copyright © 2011-2022 走看看