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 }

 

posted @ 2014-11-05 18:16  Howe_Young  阅读(470)  评论(0编辑  收藏  举报