zoukankan      html  css  js  c++  java
  • poj 2480 Longge's problem(欧拉函数)

    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个数与n的最大公约数之和。举个栗子:当n=4时,1,2,3,4与4的最大公约数分别为1,2,1,4,累加和为8。正解:1-n中每个数与n的最大公约数肯定是n的一个因子,所以我们只需要枚举n的每一个因子x∈[1,√n],然后看有多少个满足gcd(k,n)==x,即求满足gcd(k/x,n/x)==1中k的个数(用欧拉函数求解),则公式为:∑x*[gcd(k/x,n/x)==1]。
    AC代码(204ms):
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <map>
     5 #include <vector>
     6 #include <set>
     7 using namespace std;
     8 typedef long long LL;
     9 const int maxn = 1e6+5;
    10 LL n, ans;
    11 LL get_Euler(LL x){
    12     LL res = x;
    13     for(LL i = 2LL; i * i <= x; ++i) {
    14         if(x % i == 0) {
    15             res = res / i * (i - 1);
    16             while(x % i == 0) x /= i;
    17         }
    18     }
    19     if(x > 1LL) res = res / x * (x - 1);
    20     return res;
    21 }
    22 
    23 int main(){
    24     while(cin >> n) {
    25         ans = 0LL;
    26         for (LL i = 1LL; i * i <= n; ++i) {
    27             if(n % i == 0) {
    28                 ans += i * get_Euler(n / i);
    29                 if(i * i != n) ans += n / i * get_Euler(i); ///避免重复计数
    30             }
    31          }
    32          cout << ans << endl;
    33     }
    34     return 0;
    35 }
    AC代码二(32ms):思路和上面相同,只是将问题求解转换一下gcd(i, n) == (p_i)^j,即求Σ(p_i)^j [gcd(i/((p_i)^j)), n/((p_i)^j)==1],化简公式得 (k+1)* p^k - k*p^(k-1),再根据积性函数的性质得n的欧拉函数值为每种素因子对应的欧拉函数值φ((p_i)^a_i)相乘即可。时间复杂度是O(sqrt(n))。具体推导过程:传送门
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 typedef long long LL;
     6 LL n;
     7 LL solve(LL x) {
     8     LL p_i, k, ans = 1LL;
     9     for(LL i = 2LL; i * i <= x; ++i) {
    10         if(x % i == 0) {
    11             p_i = 1LL, k = 0; 
    12             while(x % i == 0) {k++, p_i *= i, x /= i;}
    13             ans *= (k + 1) * p_i - k * p_i / i; ///(k+1)*p^k - k*p^(k-1)
    14         }
    15     }
    16     if(x > 1LL) ans *= 2 * x - 1LL; 
    17     return ans;
    18 }
    19 int main() {
    20     while(cin >> n) {
    21         cout << solve(n) << endl;
    22     }
    23     return 0;
    24 }
  • 相关阅读:
    加入创业公司有什么利弊
    Find Minimum in Rotated Sorted Array II
    Search in Rotated Sorted Array II
    Search in Rotated Sorted Array
    Find Minimum in Rotated Sorted Array
    Remove Duplicates from Sorted Array
    Spiral Matrix
    Spiral Matrix II
    Symmetric Tree
    Rotate Image
  • 原文地址:https://www.cnblogs.com/acgoto/p/10284800.html
Copyright © 2011-2022 走看看