http://poj.org/problem?id=2480
大意:求解 ∑gcd(i, N) 1<=i <=N。
对于最大公约数,它有这样的性质,gcd(n,m1*m2)=gcd(nm1)*gcd(n,m2) 比如gcd(6,12)=gcd(6,3)*gcd(6,4).
我们设f(N)=∑gcd(i, N),那么它也应该是一个积性函数。(积性函数的积是积性函数,积性函数的和是积性函数)
设 其中p是和n互素的数字。
又设 ,由积性函数的性质:
(*)
同时我们知道:
欧拉函数有这样的计算方式:
所以得到:
带入(*)中:
写代码:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long LL;
int main()
{
LL n,ans;
while(cin>>n){
int len=sqrt(n*1.0);
ans=n;
LL a=0,p=1;
for(int i=2;i<=len;i++){
a=0;
if(n%i==0){
a++;
n/=i;
p=i;
while(n%i==0) {
a++;
n/=i;
}
ans=ans/p*(p+a*p-a);
}
}
if(n>1){
ans=ans/n*(n+n-1);
}
printf("%lld\n",ans);
}
return 0;
}