poj2480——Longge's problem(欧拉函数)

Longge's problem
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 9190   Accepted: 3073

Description

Longge is good at mathematics and he likes to think about hard mathematical problems which will be solved by some graceful algorithms. Now a problem comes: Given an integer N(1 < N < 2^31),you are to calculate ∑gcd(i, N) 1<=i <=N. 

"Oh, I know, I know!" Longge shouts! But do you know? Please solve it. 

Input

Input contain several test case. 
A number N per line. 

Output

For each N, output ,∑gcd(i, N) 1<=i <=N, a line

Sample Input

2
6

Sample Output

3
15


题意:给出一个数n,让你求1-n中所有的数与n的最大公约数的和。

思路:这题是欧拉函数的应用。假设x与n的最大公约数是a,也就是gcd(x,n)=a,那么我们就可以知道gcd(x/a,n/a)=1,也就是x/a与n/a互质。
这说明在1-n中与 n 的最大公约数为a的数都与n/a互质,所以我们就用欧拉函数求出1-n/a中,与n/a互质的数有多少个,其中,a是n的约数,所以遍历所有n的约数。
这题求的是与n的最大公约数的和sum,所以当a是n的约数时,sum就要加上a*欧拉(n/a);

代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<string>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<stack>
 8 #include<queue>
 9 #define eps 1e-7
10 #define ll long long
11 #define inf 0x3f3f3f3f
12 #define pi 3.141592653589793238462643383279
13 using namespace std;
14 ll euler(ll n) // 求欧拉函数值 
15 {
16     ll res = n,a = n;
17     for(ll i=2; i*i<=a; ++i)
18     {
19         if(a%i==0)
20         {
21             res = res/i*(i-1);
22             while(a%i==0) a /= i;
23         }
24     }
25     if(a > 1) res = res/a*(a-1);
26     return res;
27 }
28 
29 int main()
30 {
31     ll n;
32     while(scanf("%lld",&n)!=EOF)
33     {
34         ll ans=0;
35         for(ll i=1; i*i<=n; ++i) //遍历求n的约数 
36         {
37             if(n%i == 0)  
38             {
39                 ans += i*euler(n/i); //euler(n/i)求出与 n 的最大公约数为 i 的数有多少,再乘上公约数 i  
40                 if(n/i != i)
41                     ans += euler(i)*(n/i); //同理求出与n的最大公约数为n/i的数有多少 
42             }
43         }
44         printf("%lld\n",ans);
45     }
46     return 0;
47 }

posted @ 2018-07-17 11:01  特务依昂  阅读(199)  评论(0编辑  收藏  举报