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.
Input Input contain several test case. A number N per line.
Output For each N, output ,∑gcd(i, N) 1<=i <=N, a line
累加的数一定是n的因数,所以对于每个因数x考虑。
若x被累加,即对于某一个i,有GCD(i,n)=x。
故GCD(i/x,n/x)=1。因为1<=i<=n,故实际上这样的i的个数有phi(n/x)个。
枚举因数【注意是所有因数,不是质因数】累加即可。
#include<cstdio>
#include<cstring>
#include<cmath>
#define L long long
L p[70000];
L f(L x)
{
L i,ans=x;
L y=(L)sqrt(x+0.5);
for (i=2;i<=y;i++)
if (x%i==0)
{
ans=ans/i*(i-1);
while (x%i==0) x/=i;
}
if (x>1) ans=ans/x*(x-1);
return ans;
}
int main()
{
L i,j,m,n,n1,n2,q,x,y,z,cnt,ans;
while (scanf("%lld",&n)==1)
{
cnt=0;
for (i=1;i*i<n;i++)
if (n%i==0)
{
p[++cnt]=i;
p[++cnt]=n/i;
}
if (i*i==n) p[++cnt]=i;
if (cnt==2)
{
printf("%lld\n",2*n-1);
continue;
}
ans=0;
for (i=1;i<=cnt;i++)
ans+=p[i]*f(n/p[i]);
printf("%lld\n",ans);
}
}