数论学习笔记 - 约数

约数定义

若整数 n 除以整数 d 的余数为 0,即 d 能整除 n,则称 d 是 n 的约数,n 是 d 的倍数,记为 d|n。

算术基本定理的推论

在算术基本定理中,若正整数 N 被唯一分解为 N = p1^{c1}p2^{c2}...pm^{cm},其中 ci 都是正整数,pi 都是质数,且满足 p1<p2<...<pm,则 N 的正约数集合可写作:

{p1^{b1}p2^{b2}...pm^{bm}},其中 0 ≤ bi ≤ ci

N 的正约数个数为(Π表示连乘积符号,与∑类似):

(c1 + 1) * (c2 + 1) *...* (cm + 1) = \prod_{i=1}^{m}(ci + 1)

N 的所有正约数的和为:

\prod_{i=1}^{m}(\sum_{j=0}^{ci}(pi)^{j})

求 N 的正约数集合——试除法

若 d ≥ \sqrt{N} 是 N 的约数,则 N/d ≤ \sqrt{N} 也是 N 的约数。换言之,约数总是成对出现的(除了对于完全平方数,\sqrt{N}会单独出现)

因此,只需要扫描 d = 1~\sqrt{N},尝试 d 能否整除 N,若能整除,则 N/d 也是 N 的约数。时间复杂度为 O(\sqrt{N})

int factor[1600];
int m=0;
for(int i=1;i*i<=n;i++){
    if(n%i==0){
        factor[++m]=i;
        if(i!=n/i) factor[++m]=n/i;
    }
}
for(int i=1;i<=m;i++) cout<<factor[i]<<endl;

试除法的推论

一个整数 N 的约数个数上界为2\sqrt{N}

求 1~N 每个数的正约数集合——倍数法

若用“”试除法分别求出 1~N 每个数的正约数集合,时间复杂度过高,为O(N\sqrt{N})。可以反过来考虑,对于每个数 d,1~N 中以 d 为约数的数就是 d 的倍数 d,2d,3d,...,(N/d)*d。以下程序采用“倍数法”求出 1~N 每个数的正约数集合:

vector<int> factor[500010];
for(int i=1;i<=n;i++)
    for(int j=1;j<=n/i;j++)
        factor[i*j].push_back(i);
for(int i=1;i<=n;i++){
    for(int j=0;j<factor[i].size();j++)
        printf("%d",factor[i][j]);
    puts("");
}

上述算法的时间复杂度为 O(NlogN)

倍数法的推论

1~N 每个数的约数个数的总和大约为 NlogN

最大公约数

定义

若自然数 d 同时是自然数 a 和 b 的约数,则称 d 是 a 和 b 的公约数。在所有 a 和 b 的公约数中最大的一个,成为 a 和 b 的最大公约数,记为 gcd(a,b)。

若自然数 m 同时是自然数 a 和 b 的倍数,则称 m 是 a 和 b的最小公倍数,记为 lcm(a,b)。

同理,我们也可以定义三个数以及更多个数的最大公约数/最小公倍数。

定理

任意a,b∈N        gcd(a,b)*lcm(a,b) = a*b

九章算术 · 更相减损术

任意a,b∈N,a≥b,有gcd(a,b)=gcd(b,a-b)=gcd(a,a-b)

欧几里得算法

任意a,b∈N,b≠0        gcd(a,b)=gcd(b,a mod b)

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

使用欧几里得算法求最大公约数的复杂度为 O(log(a+b))。欧几里得算法是最常用的求最大公约数的方法。不过,因为高精度除法(取模)不容易实现,需要做高精度运算时,可考虑用更相减损数代替欧几里得算法。

互质与欧拉函数

定义

任意a,b∈N,若gcd(a,b)=1,则称 a,b 互质

对于三个数或更多个数的情况,我们把 gcd(a,b,c)=1 的情况称为 a,b,c 互质。把 gcd(a,b)=gcd(a,b)=gcd(b,c)=1 称为 a,b,c 两两互质。

欧拉函数

1~N 中与 N 互质的数的个数被称为欧拉函数,记为 \varphi (N)

\varphi (N) = N * (p1 - 1)/p1  * (p2 - 1)/p2 * (p3 - 1)/p3 * ... * (pm - 1)/pm = N * \prod_{p|N}^{}(1-1/p)

根据欧拉函数的计算式,我们只需要分解质因数,即可顺便求出欧拉函数。

int phi(int n){
    int ans=n;
    for(int i=2;i<=sqrt(n);i++){
        if(n%i==0){
            ans=ans/i*(i-1);
            while(n%i==0) n/=i;
        }
    }
    if(n>1) ans=ans/n*(n-1);
    return ans;
}

 性质:

1. 任意n>1,1~n 中与 n 互质的数的和为 n*\varphi (N)/2

2. 若 a,b 互质,则 \varphi (ab)=\varphi(a)\varphi(b)

积性函数:如果当 a,b 互质时,有 f(ab)=f(a)*f(b),那么称函数 f 为积性函数

3. 若 f 是积性函数,且在算术基本定理中 n=\prod_{i=1}^{m}pi^{ci},则f(n)=\prod_{i=1}^{m}f(p1^{ci})

4. 设 p 为质数,若 p|n 且 p^2|n,则 \varphi (n)=\varphi(n/p)*p

5. 设 p 为质数,若 p|n 且 p^2!|n,则\varphi (n)=\varphi(n/p)*(p-1)

6. \sum_{d|n}^{}\varphi (d) = n

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值