您的位置:首页 > 其它

POJ2480 Longge's problem

2016-07-15 23:25 274 查看
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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  欧拉函数