原题:http://poj.org/problem?id=2480
Longge's problem
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 6953 | Accepted: 2257 |
Description
Longge is good at mathematics and he likes to think about hard mathematical problems which will be solved by some graceful algorithms. Now a problem comes: Given an integer N(1 < N < 2^31),you are to calculate ∑gcd(i, N) 1<=i <=N.
"Oh, I know, I know!" Longge shouts! But do you know? Please solve it.
"Oh, I know, I know!" Longge shouts! But do you know? Please solve it.
Input
Input contain several test case.
A number N per line.
A number N per line.
Output
For each N, output ,∑gcd(i, N) 1<=i <=N, a line
Sample Input
2 6
Sample Output
3 15
思路:(φ(n)为欧拉函数)当gcd(x,n)=p(p为常数)时,x,n同时除以p之后,就会变得和n/p互质,p在x中有φ(n/p)个,和为p*φ(n/p)个。所以我们要计算∑gcd(i, n) 1<=i <=n,只需要根据gcd的值不同,分类进行计算即可,总结成公式:∑p*φ(n/p)。同时因为gcd(n,k) -最大公因子,当k固定时是积性函数,根据积性函数性质可得f(n)=∑gcd(i, n)这也是一个积性函数,f(n) = f(p1^a1)*f(p2^a2)*...f(pr^ar)。
f(pi^ai) = pi^ai*(1+ai*(1-1/pi))
f(n) =p1^a1*p2^a2...*pr^ar*(1+a1*(1-1/p1))*(1+a2*(1-1/p2))*……= n*(1+a1*(1-1/p1))*(1+a2*(1-1/p2))*……
AC代码:
#include <stdio.h>
#define LL __int64
/*
author:YangSir
time:2014/5/12
*/
double f(LL n)
{
double ans=n,num;
LL i;
for(i=2;i*i<=n;i++)
{
if(n%i==0)
{
num=0;
while(n%i==0)
{
n/=i;
num++;
}
ans*=(1+num*(i-1)/i);//就是上面推出的公式
}
}
if(n>1)
ans=ans/n*(2*n-1);
return ans;
}
int main()
{
LL n;
while(~scanf("%I64d",&n))
printf("%.0lf\n",f(n));
return 0;
}