UVA 11426 gcd求和

UVA 11426 gcd求和

O - GCD - Extreme (II)
Time Limit:10000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu

Description

 

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                              Output for Sample Input

10

100

200000

0

 

67

13015

143295493160

 


Problemsetter: Shahriar Manzoor

Special Thanks: SyedMonowarHossain

题意:对给定的n,输出1~n的所有的不同数字的数对的gcd的和
思路:设答案为F(n)
       显然F(n)=F(n-1)+ [i=1~n-1求和]gcd(n,i);
令f(n)= [i=1~n-1求和]gcd(n,i);
对gcd(n,i)=x,(i<n),x为n的约数(x<n)
则gcd(n/x,i/x)=1;(x为n的约数)
则符合条件的i的个数为s(n,x)=euler[n/x]也就是小于n/i且与n/i互质的数的个数即欧拉函数
f(n)=[]x*s(n,x)=[]x*euler[n/x] ([]为求和)
于是按照仿照素数筛法对每个i筛出i的倍数筛出1~maxn的f[i]即可.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<math.h>
#include<cctype>
#define ll long long
#define REP(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define REPP(i,a,b,t) for(int (i)=(a);(i)<=(b);(i)+=(t))
#define PII pair<int,int>
#define MP make_pair
#define PB push_back
#define RI(x) scanf("%d",&(x))
#define RLL(x) scanf("%lld",&(x))
#define RI64(x) scanf("%I64d",&(x))
#define DRI(x) int x;scanf("%d",&(x))
#define DRLL(x) ll x;scanf("%lld",&(x))
#define DRI64(x) llx;scanf("%I64d",&(x))
#define MS0(a) memset((a),0,sizeof((a)))
#define MS1(a) memset((a),0,sizeof((a)))
#define MS(a,b) memset((a),(b),sizeof((a)))

using namespace std;

const int maxn=4000100;
const int INF=(1<<29);
const double EPS=0.0000000001;
const double Pi=acos(-1.0);

ll n;
int euler[maxn];
ll F[maxn],f[maxn];

void getEuler()
{
    MS0(euler);
    euler[1]=1;
    REP(i,2,maxn-1){
        if(!euler[i]){
            REPP(j,i,maxn-1,i){
                if(!euler[j]) euler[j]=j;
                euler[j]=euler[j]/i*(i-1);
            }
        }
    }
}

int main()
{
    getEuler();
    MS0(f);
    REP(i,1,maxn-1){
        REPP(j,i*2,maxn-1,i) f[j]+=i*euler[j/i];
    }
    MS0(F);
    REP(i,1,maxn-1) F[i]=F[i-1]+f[i];
    while(cin>>n,n){
        cout<<F[n]<<endl;
    }
    return 0;
}
View Code

 

posted @ 2015-06-11 19:23  __560  阅读(506)  评论(0编辑  收藏  举报