给出一个n,求1-n这n个数,同n的最大公约数的和。比如:n = 6
1,2,3,4,5,6 同6的最大公约数分别为1,2,3,2,1,6,加在一起 = 15
Input
1个数N(N <= 10^9)
OutPut
公约数之和
Input示例
6
Output示例
15
AC代码:
/**
*@xiaoran
*1 2 3 4 5 6
*1 2 3 2 1 6
*2个1,2个2,1个3,1个6,注意后面的值都是n的因子。
*现在我们只需要计算出各个因子的个数就行了,
*那么1的个数是与n互质的个数,即欧拉函数的值
*2的个数k=Phi(n/2),
*对于n的因子i的个数k=Phi(n/i),sum+=k*i,
*/
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<ctime>
#define LOCAL
#define LL long long
using namespace std;
LL Phi(int n){//求欧拉函数
if(n==1) return 1;
LL ans=n;
int k=(int) sqrt(n+0.5);
for(int i=2;i<=k;i++){
if(n%i==0){
ans=ans*(i-1)/i;
}
while(n%i==0) n/=i;
}
if(n>1) ans=ans*(n-1)/n;
return ans;
}
int gcd(int a,int b){
int r;
if(b==0) return a;
while(b){
r=a%b;
a=b;
b=r;
}
return a;
}
int PK(int k,int n){
int s=1;
for(int i=k*2;i<n;i+=k){//计算k的个数
if(gcd(n,i)>k) continue;
s++;
}
return s;
}
int main()
{
/*
#ifdef LOCAL
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
*/
int n;
while(cin>>n){
LL t1=clock();
int k=(int) sqrt(n+0.5);
LL ans=n;
for(int i=2;i<=k;i++){
if(n%i==0){
//cout<<PK(i,n)<<" "<<PK(n/i,n)<<endl;
ans+=Phi(n/i)*i+(n/i)*Phi(i);
}
}
ans+=Phi(n);
if(k*k==n){
ans-=k*Phi(k);
}
cout<<ans<<endl;
LL t2=clock();
//cout<<t2-t1<<endl;
}
return 0;
}
原文:http://blog.csdn.net/fool_ran/article/details/44685865