POJ 2480 Longge's problem(欧拉函数)

题目链接

前传:本来之前在高中的一个OJ上看见的,SDOI上的一个题,看着很“数论”,想了想,没想法。。。看了看DISCUSS,说是POJ上的原题,然后看了一下DISCUSS说是欧拉函数,不会。。。然后就放下,最近遇见了很多这样类似的问题,所以先把这个裸题给过了。。。查了一下,有结论。。。

∑gcd(i, n)  = sum(i*euler(n/i));为啥会这样呢?我自己手算了一下10的情况,规律还是挺明显的,1-n中可以整除i的个数是n/i,这些数与n的最大公约数为i的时候,不就相当于这些都数除以i,然后寻找互质的数,所以i*euler(n/i)就是1-n中公约数是i的总和。欧拉函数用的是模版,本来还想推导一下,实在是没想出这个公式怎么来的,先用着吧。

PS:没注意n是完全平方数的情况,错了两次。。。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <vector>
 6 #include <cmath>
 7 #include <map>
 8 #define ll __int64
 9 using namespace std;
10 ll euler(ll n)
11 {
12     ll i,m = (ll)sqrt(n + 0.5),ans = n;
13     for(i = 2;i <= m;i ++)
14     {
15         if(n%i == 0)
16         ans = ans/i*(i-1);
17         while(n%i == 0) n /= i;
18     }
19     if(n > 1) ans = ans/n*(n-1);
20     return ans;
21 }
22 int main()
23 {
24     ll n,ans,i;
25     while(scanf("%I64d",&n)!=EOF)
26     {
27         ans = 0;
28         for(i = 1;i*i <= n;i ++)
29         {
30             if(n%i == 0)
31             {
32                 ans += i*euler(n/i);
33                 if(i*i != n)
34                 ans += n/i*euler(i);
35             }
36         }
37         printf("%I64d\n",ans);
38     }
39     return 0;
40 }

 

 

posted @ 2012-09-07 21:33  Naix_x  阅读(216)  评论(0编辑  收藏  举报