Acwing-基础算法课笔记之数学知识(约数)
一、试除法求约数
1、概念
∙
\bullet
∙利用试除法即可
如果我们要枚举较小的约数,则
d
≤
n
d
d\le \frac{n}{d}
d≤dn,即
d
≤
n
d\le \sqrt{\smash[b]{n}}
d≤n,那么较大的约束可以直接算出来。
2、代码模板
vector<int> get_divisors(int x)
{
vector<int> res;
for (int i = 1; i <= x / i; i ++ )
if (x % i == 0)
{
res.push_back(i);
if (i != x / i) res.push_back(x / i);
}
sort(res.begin(), res.end());
return res;
}
二、约数个数
1、概述
利用短除法分解质因数
设要求的数是
N
N
N
利用短除法分解质因数得
N
=
p
1
n
1
⋅
p
2
n
2
⋅
p
3
n
3
⋅
⋅
⋅
⋅
⋅
p
n
n
α
N=p_1^{n_1}\cdot p_2^{n_2}\cdot p_3^{n_3}\cdot\cdot\cdot\cdot\cdot p_n^{n_α}
N=p1n1⋅p2n2⋅p3n3⋅⋅⋅⋅⋅pnnα
所以
N
N
N的约数个数为
(
n
1
+
1
)
⋅
(
n
2
+
1
)
⋅
(
n
3
+
1
)
⋅
⋅
⋅
⋅
⋅
(
n
α
+
1
)
(n_1+1)\cdot (n_2+1)\cdot (n_3+1)\cdot\cdot\cdot\cdot\cdot (n_α+1)
(n1+1)⋅(n2+1)⋅(n3+1)⋅⋅⋅⋅⋅(nα+1)
2、过程模拟
要求360的约数个数,步骤如下:
360
=
2
3
×
3
2
×
5
1
360=2^{3}\times 3^{2}\times 5^{1}
360=23×32×51
所以
360
360
360的约数个数是
(
3
+
1
)
×
(
2
+
1
)
×
(
1
+
1
)
=
24
(3+1)\times (2+1)\times (1+1)=24
(3+1)×(2+1)×(1+1)=24
三、约数之和
1、概述
利用短除法分解质因数
设要求的数是
N
N
N
利用短除法分解质因数得
N
=
p
1
n
1
⋅
p
2
n
2
⋅
p
3
n
3
⋅
⋅
⋅
⋅
⋅
p
n
n
α
N=p_1^{n_1}\cdot p_2^{n_2}\cdot p_3^{n_3}\cdot\cdot\cdot\cdot\cdot p_n^{n_α}
N=p1n1⋅p2n2⋅p3n3⋅⋅⋅⋅⋅pnnα
所以
N
N
N的约数之和为
(
p
1
0
+
p
1
1
+
p
1
2
+
⋅
⋅
⋅
+
p
1
n
1
)
⋅
(
p
2
0
+
p
2
1
+
p
2
2
+
⋅
⋅
⋅
+
p
2
n
2
)
⋅
(
p
3
0
+
p
3
1
+
p
3
2
+
⋅
⋅
⋅
+
p
3
n
3
)
⋅
⋅
⋅
⋅
⋅
(
p
n
0
+
p
n
1
+
p
n
2
+
⋅
⋅
⋅
+
p
n
n
α
)
(p_1^{0}+p_1^{1}+p_1^{2}+\cdot\cdot\cdot+p_1^{n_1})\cdot(p_2^{0}+p_2^{1}+p_2^{2}+\cdot\cdot\cdot+p_2^{n_2})\cdot(p_3^{0}+p_3^{1}+p_3^{2}+\cdot\cdot\cdot+p_3^{n_3})\cdot\cdot\cdot\cdot\cdot(p_n^{0}+p_n^{1}+p_n^{2}+\cdot\cdot\cdot+p_n^{n_α})
(p10+p11+p12+⋅⋅⋅+p1n1)⋅(p20+p21+p22+⋅⋅⋅+p2n2)⋅(p30+p31+p32+⋅⋅⋅+p3n3)⋅⋅⋅⋅⋅(pn0+pn1+pn2+⋅⋅⋅+pnnα)
2、过程模拟
要求360的约数个数,步骤如下:
360
=
2
3
×
3
2
×
5
1
360=2^{3}\times 3^{2}\times 5^{1}
360=23×32×51
所以
360
360
360的约数个数是
(
2
0
+
2
1
+
2
2
+
2
3
)
×
(
3
0
+
3
1
+
3
2
)
×
(
5
0
+
5
1
)
(2^{0}+2^{1}+2^{2}+2^{3})\times(3^{0}+3^{1}+3^{2})\times(5^{0}+5^{1})
(20+21+22+23)×(30+31+32)×(50+51)
四、最大公约数(欧几里得算法即辗转相除法)
1、举例
∙
\bullet
∙欧几里得在几何原本当中举的例子(铺瓷砖)
例如,求
(
6
,
16
)
(6,16)
(6,16)的最大公约数,步骤如下:
所以,
(
6
,
16
)
(6,16)
(6,16)的最大公约数是
2
2
2。
∙
\bullet
∙当两个数比较大时,用辗转相除法
例如,求
(
12921
,
4234
)
(12921,4234)
(12921,4234)的最大公约数,步骤如下:
所以,
(
12921
,
4234
)
(12921,4234)
(12921,4234)的最大公约数是
73
73
73。
由此可知,设
A
A
A为被除数,
B
B
B为除数,
Q
Q
Q为商数,
R
R
R为余数
所以,
(
A
,
B
)
=
(
B
,
R
)
(A,B)=(B,R)
(A,B)=(B,R)
2、证明欧几里得算法
g c d ( a , b ) = g c d ( b , a m o d b ) gcd(a,b)=gcd(b,amodb) gcd(a,b)=gcd(b,amodb)
不妨设
a
>
b
a>b
a>b,令
a
=
k
⋅
b
+
c
a=k\cdot b+c
a=k⋅b+c,其中
k
k
k是商数,
c
c
c是余数,
c
=
a
m
o
d
b
c=amodb
c=amodb
不妨设
d
=
g
c
d
(
a
,
b
)
d=gcd(a,b)
d=gcd(a,b),则设
{
a
=
p
1
⋅
d
b
=
p
2
⋅
d
\begin{cases} a={p_1}\cdot d\\ b={p_2}\cdot d \end{cases}
{a=p1⋅db=p2⋅d,(
p
1
{p_1}
p1,
p
2
{p_2}
p2互质)
代入得, p 1 ⋅ d = k ⋅ p 2 ⋅ d + c {p_1}\cdot d=k\cdot {p_2}\cdot d+c p1⋅d=k⋅p2⋅d+c ⇒ \Rarr ⇒ c = d ⋅ ( p 1 − k ⋅ p 2 ) c=d\cdot({p_1}-k\cdot {p_2}) c=d⋅(p1−k⋅p2)
结论: g c d ( p 1 ⋅ d , p 2 ⋅ d ) = g c d ( p 2 ⋅ d , d ⋅ ( p 1 − k ⋅ p 2 ) ) = d gcd({p_1}\cdot d,{p_2}\cdot d)=gcd({p_2}\cdot d,d\cdot({p_1}-k\cdot {p_2}))=d gcd(p1⋅d,p2⋅d)=gcd(p2⋅d,d⋅(p1−k⋅p2))=d
证明: p 2 {p_2} p2与 p 1 − k ⋅ p 2 {p_1}-k\cdot {p_2} p1−k⋅p2互质即可(反证法)
若 p 2 {p_2} p2与 p 1 − k ⋅ p 2 {p_1}-k\cdot {p_2} p1−k⋅p2不互质,则设其最大公因数为 t t t,设 { p 1 = t ⋅ m , ( m , n 互质 ) p 1 − k ⋅ p 2 = t ⋅ n ,( t ≥ 2 ) \begin{cases} {p_1}=t\cdot m,(m,n互质)\\ {p_1}-k\cdot {p_2}=t\cdot n,(t\ge2) \end{cases} {p1=t⋅m,(m,n互质)p1−k⋅p2=t⋅n,(t≥2)
所以, p 1 − k ⋅ t ⋅ m = t ⋅ n {p_1}-k\cdot t\cdot m=t\cdot n p1−k⋅t⋅m=t⋅n, { p 1 = t ⋅ ( n + k ⋅ m ) p 2 = t ⋅ m \begin{cases} {p_1}=t\cdot (n+k\cdot m)\\ {p_2}=t\cdot m \end{cases} {p1=t⋅(n+k⋅m)p2=t⋅m
所以, p 1 = t ⋅ ( n + k ⋅ m ) {p_1}=t\cdot (n+k\cdot m) p1=t⋅(n+k⋅m), { a = p 1 ⋅ d = t ⋅ d ⋅ ( n + k ⋅ m ) b = p 2 ⋅ d = t ⋅ m ⋅ d = t ⋅ d ⋅ m \begin{cases} a={p_1}\cdot d=t\cdot d\cdot (n+k\cdot m)\\ b={p_2}\cdot d=t\cdot m\cdot d=t\cdot d\cdot m \end{cases} {a=p1⋅d=t⋅d⋅(n+k⋅m)b=p2⋅d=t⋅m⋅d=t⋅d⋅m
所以, g c d ( a , b ) = t ⋅ d ⇒ x gcd(a,b)=t\cdot d\Rarr x gcd(a,b)=t⋅d⇒x。
3、代码模板
int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}