算术基本定理

一、定理内容

算术基本定理,又名唯一分解定理。若\(a>1\),那么必有\(a=p_1 ^ {\alpha _1}p_2^{\alpha _2}...p_s^{\alpha _s}\),其中\(p_j(1<=j<=s)\)是两两不相同的质数,\(a_j(1<=j<=s)\)表示对应质数的幂次(出现的次数)。若在不计次序的意义下,该分解式是唯一的。

二、分解质因数

/**
 * 功能:分解质数因数
 * @param x 待分解的数字
 * @param a 分解后的数组
 * @return 数组的最后一个元素下标
 */
int Decomposition(int x, int a[]) {
    int cnt = 0;
    for (int i = 2; i <= x / i; i++)
        while (x % i == 0) {
            x /= i;
            a[++cnt] = i;
        }
    if (x > 1)a[++cnt] = x;
    return cnt;
}

const int N = 110;
int a[N];

//用法:
int cnt = Decomposition(12, a);
for (int i = 1; i <= cnt; i++) cout << a[i] << " ";

三、推论1

\(d\)\(a\)的约数的充要条件是:

\(a=p_1^{\alpha _1}p_2^{\alpha _2}...p_s^{\alpha _s}\)

\(d=p_1^{e_1}p_2^{e_2}...p_s^{e_s}\),\(0<=e_j<=a_j\),\(1<=j<=s\),即\(d\)中每个质数的幂次都不超过\(a\)的幂次。

这个推论用人话说就是:

如果\(d|a\),那么必然:

(1)、\(d\)里的每一个因子,都能在\(a\)的因子中找到。

(2)、\(d\)中每一个因子的幂,必须小于等于\(a\)中同因子的幂。

(3)、如果有一个因子在\(a\)中存在,而在\(d\)中不存在,可以认为此因子在\(d\)中也存在,只是幂为\(0\)

四、推论2

\(a=p_1^{\alpha _1}p_2^{\alpha _2}...p_s^{\alpha _s}\)

\(b=p_1^{\beta _1}p_2^{\beta _2}...p_s^{\beta _s}\)

(这里允许某些\(\alpha _j\)\(\beta _j\))为零,那么\((a,b)=p_1^{\delta _1}p_2^{\delta _2}...p_s^{\delta _s}\) ,\(\delta _j=min(\alpha _j,\beta _j)\),\(1<=j<=s\),以及\([a,b]=p_1^{\gamma _1}p_2^{\gamma _2}...p_s^{\gamma _s}\),\(\gamma _j=max(\alpha _j,\beta _j)\),\(1<=j<=s\)

举个栗子:

\(10=2\times 5,16=2^4\),那么

\((10,16)=2^{min(1,4)} \times 5 ^{min(1,0)}=2^1\times 5^0=2\)

\([10,16]=2^{max(1,4)}\times 5 ^{max(1,0)}=2^4\times 5^1=80\)

五、约数个数定理

对于一个大于\(1\)正整数\(n\)可以分解质因数:\(n=p_1^{a_1}*p_2^{a_2}*p_3^{a_3}*…*p_k^{a_k}\)

\(n\)的约数个数=\((a_1+1)(a_2+1)(a_3+1)…(a_k+1)\)

注意:这里约数的个数只与幂有关,与具体是哪个质数因子无关!

举个栗子:
例题:正整数\(378000\)共有多少个正约数?

解:将\(378000\)分解质因数\(378000=2^4×3^3×5^3×7^1\)

由约数个数定理可知\(378000\)共有正约数\((4+1)×(3+1)×(3+1)×(1+1)=160\)个。

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;

const int N = 110;
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 p: primes) res = res * (p.second + 1) % mod;
    //输出结果
    cout << res << endl;
    return 0;
}

六、约数和定理

对于一个大于\(1\)正整数n可以分解质因数:\(n=p_1^{a_1}*p_2^{a_2}*p_3^{a_3}*…*p_k^{a_k}\),

\(n\)的正约数个数=\((a_1+1)(a_2+1)(a_3+1)…(a_k+1)\)个,

那么\(n\)\((a_1+1)(a_+1)(a_+1)…(a_+1)\)个正约数的和为

\(n\)的约数和\(=(p_1^0+p_1^1+p_1^2+…p_1^{a_1})(p_2^0+p_2^1+p_2^2+…p_2^{a_2})...(p_k^0+p_k^1+p_k^2+…p_k^{a_k})\)

注意:这里约数和不光与幂有关,还与具体是哪个质数因子有关!

举个栗子:

例题:正整数\(360\)的所有正约数的和是多少?

解:将\(360\)分解质因数可得
\(360=2^3*3^2*5^1\)

由约数和定理可知,\(360\)所有正约数的和为
\((2^0+2^1+2^2+2^3)×(3^0+3^1+3^2)×(5^0+5^1)=(1+2+4+8)×(1+3+9)×(1+5)=15×13×6=1170\)

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N = 110;
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 p : primes) {
        LL a = p.first, b = p.second;
        LL t = 1;
        while (b--) t = (t * a + 1) % mod;
        res = res * t % mod;
    }
    cout << res << endl;
    return 0;
}
posted @ 2021-08-30 13:50  糖豆爸爸  阅读(840)  评论(0编辑  收藏  举报
Live2D