描述
Given an integer N(1 < N < 2^31),you are to calculate ∑gcd(i, N) 1<=i <=N.
思路
通过数论知识,可以知道这是一个积性函数。(具体我也不清楚,记住就行了。)分解质因数,对于每个p^a,可以推倒一个类似递归的方法算出。(函数calc)
注意,N分解完后,会剩下一个大质数,别忘乘上。
代码
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
long long int calc(int p,int a)
{
long long int ret=1,x=1;
for (int i=0;i<a;i++)
{
ret=ret*p+x*(p-1);
x*=p;
}
return ret;
}
bool use[70001];
int pr[70001];
long long int cnt;
void calcprime()
{
cnt=0;
memset(use,0,sizeof(use));
use[0]=1;use[1]=1;
for (int i=2;i<270;i++)
if (!use[i])
for (int j=i*i;j<70000;j+=i)
use[j]=1;
for (int i=2;i<70000;i++)
if (!use[i])
pr[cnt++]=i;
}
long long ans;
void solve(long long int x)
{
ans=1;
long long int tmp;
tx=x;
for (int i=0;i<cnt && pr[i]<=x;i++)
if (x%pr[i]==0)
{
tmp=0;
while (x%pr[i]==0)
tmp++,x/=pr[i];
ans*=calc(pr[i],tmp);
}
ans*=calc(x,1);
printf("%I64d\n",ans);
}
int main()
{
long long int n;
calcprime();
while(scanf("%I64d",&n)!=EOF)
{
solve(n);
}
return 0;
}
链接: http://poj.org/problem?id=2480