NYOJ-569最大公约数之和
题目链接: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互质的个数
以上是推倒过程, 这个题目主要就是球欧拉函数和推倒出这个表达式
代码如下:
1 #include<iostream> 2 #include <cstdio> 3 using namespace std; 4 5 int Eular(int n) 6 { 7 int ans = n; 8 for(int i = 2; i * i <= n; i++) 9 { 10 if(n % i == 0) //如果i 和 n不互质, 则i的倍数和n也不互质 11 { 12 ans -= ans / i; //去除掉i的倍数 13 while(n % i == 0) //去掉n中所有i的因子 14 n /= i; 15 if(n == 1) // n = 1时, 所以因子排除完毕 16 break; 17 } 18 } 19 if(n != 1) //如果n为质数 20 ans -= ans / n; 21 return ans; 22 } 23 int main() 24 { 25 26 int n; 27 while(~scanf("%d", &n)) 28 { 29 long long sum = 0; 30 for(int i = 1; i * i <= n; i++) 31 { 32 if(i * i == n) //这时只需要加一次 33 { 34 sum += ((long long)(Eular(i) * i)); 35 break; 36 } 37 if(n % i == 0) //这里例如就是Eular(2) * 6 和 Eular(6) * 2; 38 { 39 sum += ((long long)(Eular(i) * (n / i))); 40 sum += ((long long)(Eular(n / i) * i)); 41 } 42 } 43 printf("%lld\n", sum); 44 } 45 }