-
描述
-
题目很简单,求出:
-
输入
- 每行一个数n(n<2^31),以文件结束。 输出
- 每个结果占一行。 样例输入
-
12
样例输出
-
40
这道题采用了欧拉函数的性质,
1-12与12的最大公约数和就为
φ(1)*12+φ(2)*6+φ(3)*4+φ(4)*3+φ(6)*2+φ(12)*1
直接算出来就行了。
#include <stdio.h>
#include <math.h>
#define LL long long
LL ans;
LL euler ( int n ) //求出欧拉函数的值
{
LL ret = n;
int m = sqrt ( n ); //用i*i不知道为什么运行不出结果,可能陷入了死循环
for ( int i = 2; i <= m; i ++ ) //因为i*i超过整型范围了
{
if ( n%i == 0 )
{
ret = ret/i*( i-1 ); //去掉质因子的个数
while ( n%i == 0 )
n = n/i;
}
}
if ( n > 1 ) //余数可能不为1
ret = ret/n*( n-1 );
return ret;
}
void solve ( int n )
{
int m = sqrt ( n );
for ( int i = 1; i <= m; i ++ )
{
if ( n%i == 0 )
{
ans = ans+euler ( i )*n/i;
if ( i != n/i ) //两个因子相同时,只需要算一个就行了
ans = ans+euler ( n/i )*i;
}
}
}
int main ( )
{
int n;
while ( ~ scanf ( "%d", &n ) )
{
ans = 0;
solve ( n );
printf ( "%lld\n", ans );
}
return 0;
}