zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    45     }
    46     return 0;
    47 }
    
    
  • 相关阅读:
    耐心
    百度年会
    聊聊今年的春节联欢晚会
    网速调查
    热烈欢迎两位园友加盟
    遥远的路
    博客园博客程序架构设计图初稿
    [公告]社区与博客实现了登录整合
    博客园上海俱乐部第二次活动继续报道
    [收藏]《观察与思考》:相信中国,寻找下一个比尔·盖茨
  • 原文地址:https://www.cnblogs.com/tuyang1129/p/9322235.html
Copyright © 2011-2022 走看看