2705: [SDOI2012]Longge的问题
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1966 Solved: 1230
[ Submit][ Status][ Discuss]
Description
Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。
Input
一个整数,为N。
Output
一个整数,为所求的答案。
Sample Input
6
Sample Output
15
HINT
【数据范围】
对于60%的数据,0<N<=2^16。
对于100%的数据,0<N<=2^32。
题解:这道题目求的是∑gcd(i,n) (1<=i<=n)。 枚举n的约数k,令s(k)为满足gcd(i,n)=k的个数,所以ans=∑(k*s(k))。
因为gcd(i,n)=k,所以gcd(i/k,n/k)=1,于是s(k)=euler(n/k)。
代码如下:
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL long long
LL m;
LL euler(LL k)
{
LL res=k,i;
for(i=2;i*i<=k;++i)
{
if(k%i==0)
res=res/i*(i-1);
while(k%i==0)
k/=i;
}
if(k>1)
res=res/k*(k-1);
return res;
}
int main()
{
LL ans,n,i;
while(scanf("%lld",&n)!=EOF)
{
m=sqrt(n);
ans=0;
for(i=1;i<=m;++i)
{
if(n%i==0)
{
ans+=(LL)i*euler(n/i);
if(i*i<n)
ans+=(LL)(n/i)*euler(i);
}
}
printf("%lld\n",ans);
}
}