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 }

 

 

你可能感兴趣的:(long)