【數學】約數、約數個數、約數之和、最大公約數


約數,外文名:Divisor,別名:因數

簡介:
約數,又稱因數。整數a除以整數b(b≠0) 除得的商正好是整數而沒有余數,我們就說a能被b整除,或b能整除a。a稱為b的倍數,b稱為a的約數。一個整數的約數是有限的。同時,它可以在特定情況下成為公約數。

1.試除法求約數

  • \(“d\  | \ n”\)代表的含義是 \(d\) 能整除 \(n\) ,(這里的 \(“|”\) 代表整除)

  • 一個合數的約數總是成對出現的,如果 \(d|n\) ,那么 \(\frac{n}{d}|n\),因此我們求約數的時候,只需要求的那一個數就行了,即只需枚舉 \(d<=\frac{n}{d}\),即 \(d∗d<=n,d<=sqrt(n)\)

vector<int> get_divisors(int n)
{
    vector<int> res;
    for(int i = 1; i <= n / i; i ++ ) // n / i意思就是枚舉到根號n
    {
        if(n % i == 0)
        {
            res.push_back(i);
            if(i != n / i) res.push_back(n / i); //有可能出現i * i = n的情況,即兩個約數相同,我們只保留一個
        }
    }
    sort(res.begin(), res.end());

    return res;
}

2.約數個數
由算術基本定理:任何一個大於1的自然數 ,如果N不為質數,都可以唯一分解成有限個質數的乘積
\(N=P_1^{a1}P_2^{a2}···P_n^{an}\) ,這里 \(P_1<P_2<···<P_n\)且均為質數,其諸指數是正整數。
即一個非質數必然可以分解為唯一的一組幾個質數的積。
證明:
image
\(n\)的正整數約數個數為:
\(\prod_{i=1}^n(a_i+1)=(a_1+1)(a_2+1) \ldots (a_n+1)\)

#include <iostream>
#include <algorithm>
#include <unordered_map>

using namespace std;

typedef long long LL;

const int mod = 1e9 + 7;

int main()
{
    int n;
    cin >> n;

    unordered_map<int,int> primes;
    while(n --)
    {
        int x;
        cin >> x;

        for(int i = 2; i <= x / i; i ++ ) //把x分解,從2開始枚舉,枚舉到根號x(x/i這里就相當於根號x)
        {
            while(x % i == 0)
            {
                x /= i;
                primes[i] ++; //i的質因數的指數加一
            }
        }
        if(x > 1) primes[x] ++; //如果x>1,說明x是一個比較大的質因數,然后把剩下的這個數加上就可以了
        /*回顧之前講過的性質:一個合數n中最多只包含一個大於根號n的質因子,所以這里只需要特判一下加上最后那個質因子即可*/
    }
    //上面這步做完后,哈希表primes里就存了所有質因數的指數

    LL res = 1;

    //枚舉所有質因數
    for(auto c : primes) res = res * (c.second + 1) % mod; //把a1~an的質因子的次數累加起來就可以了

    cout << res << endl;

    return 0;
}

3.約數之和
約數和公式:image
上式中每個括號里是每個質數的任意次冪之和。
image

#include <iostream>
#include <algorithm>
#include <unordered_map>

using namespace std;

typedef long long LL;

const int mod = 1e9 + 7;

int main()
{
    int n;
    cin >> n;
    
    unordered_map<int,int> primes;
    while(n --)
    {
        int x;
        cin >> x;
        
        for(int i = 2; i <= x / i; i ++ )
        {
            while(x % i == 0)
            {
                x /= i;
                primes[i] ++;
            }
        }
        if(x > 1) primes[x] ++;
    }
    
    LL res = 1;
    for(auto prime : primes)
    {
        int p = prime.first, a = prime.second; //p為底數,a為指數
        LL t = 1;
        
        while(a --) //套公式,從0加到a
        {
            t = (t * p + 1) % mod;
        }
        
        res = res * t % mod;
    }
    
    cout << res << endl;

    return 0;
}

4.最大公約數
image

int gcd(int a, int b)
{
    return b ? gcd(b, a % b) : a;
}

參考:
https://zhuanlan.zhihu.com/p/353613695
https://www.cnblogs.com/BaseAI/p/12056017.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM