题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=569
此题目可以用筛选法的思想来做,但是用到一个欧拉函数
gcd(1,12)=1,gcd(5,12)=1,gcd(7,12)=1,gcd(11,12)=1,
gcd(2,12)=2,gcd(10,12)=2,
gcd(3,12)=3,gcd(9,12)=3,
gcd(4,12)=4,gcd(8,12)=4,
gcd(6,12)=6,
gcd(12,12)=12,
gcd(1,12)+gcd(2,12)+gcd(3,12)+gcd(4,12)+gcd(5,12)+gcd(6,12)+
gcd(7,12)+gcd(8,12)+gcd(9,12)+gcd(10,12)+gcd(11,12)+gcd(12,12)
=4*1+2*2+2*3+2*4+1*6+1*12=40
φ(12)*1+φ(6)*2+φ(4)*3+φ(3)*4+φ(2)*6+φ(1)*12
=4*1+2*2+2*3+2*4+1*6+1*12
=40
其中φ(x)是欧拉函数,意思就是从1-x中所有与x互质的个数
以上是推倒过程, 这个题目主要就是球欧拉函数和推倒出这个表达式
代码如下:
#include<iostream>
#include <cstdio>
using namespace std; int Eular(int n)
{
int ans = n;
for(int i = ; i * i <= n; i++)
{
if(n % i == ) //如果i 和 n不互质, 则i的倍数和n也不互质
{
ans -= ans / i; //去除掉i的倍数
while(n % i == ) //去掉n中所有i的因子
n /= i;
if(n == ) // n = 1时, 所以因子排除完毕
break;
}
}
if(n != ) //如果n为质数
ans -= ans / n;
return ans;
}
int main()
{ int n;
while(~scanf("%d", &n))
{
long long sum = ;
for(int i = ; i * i <= n; i++)
{
if(i * i == n) //这时只需要加一次
{
sum += ((long long)(Eular(i) * i));
break;
}
if(n % i == ) //这里例如就是Eular(2) * 6 和 Eular(6) * 2;
{
sum += ((long long)(Eular(i) * (n / i)));
sum += ((long long)(Eular(n / i) * i));
}
}
printf("%lld\n", sum);
}
}