整除
定义与性质
设
- 设
,那么
- 设
,那么
- 设
,那么
约数
定义:若
性质:
0是所有非0正数的倍数,对于整数
,b的约数只有有限个 平凡约数:对于整数
,±1、±b是b的平凡约数 当
时,只有两个平凡约数 真约数:b的其他约数
,当d遍历b的全体约数时, 也遍历b的全体约数 ,则当d遍历b时全体正约数时, 也遍历b的全体约数
没有特殊说明,约数总是指向正约数
余数
余数
设
其中这里的d表示不同取值区间的余数,无论整数d取何值,r统称余数,
带余数除法
一般情况下,
r可以写成
余数的性质
- 任一整数被正整数a除后,余数一定是且仅是0到(a-1)这a个数中的一个
- 相邻的a个整数被正整数a除后,恰好取到上述a个余数,特别的,一定有且仅有一个数被a整除
最大公约数与最小公倍数
最大公约数
定义
一组整数的公约数,是指同时是这组数中每一个数的约数的数。gcd(a,b)
性质
若
,则
进而对任意,都有
对不全为 0 的整数
和非零整数 ,
对不全为 0 的整数
,若 ,则
若
且 ,则 若
且 ,则 若
,则 若
,则
特别地,若 ,则
对整数
,若存在 使
且对任意 有 ,则
求法
欧几里得算法
对于正整数
代码实现如下:
递归版
1 | ll gcd(ll a,ll b){ |
位运算版
1 | ll gcd(ll a,ll b){ |
多个数求gcd,答案一定是每个数的约数,那么也一定是每相邻两个数的约数。我们采用归纳法,可以证明,每次取出两个数求出答案后再放回去,不会对所需要的答案造成影响。
扩展欧几里得算法
exgcd是用来求形如
证明略,一组可行解形如
代码:
1 | ll exgcd(ll a,ll b,ll &x,ll &y){ |
更相减损术
这个方法出自九章算术:
任意给定两个正整数,判断是否都是偶数,若是,则用2约分,若不是,则执行下一步- 用较大的数减较小的数,接着将所得差与减数比较,并以大数减小数,操作至所得减数和差相等为止,则该等数就是所求的最大公因数
互素
若
多个整数互素,不一定两两互素
快速GCD
预处理
预处理:
- 预处理所有
,其中 的gcd,可以以 推出 - 预处理
以内质数
查询:
设
若
1 | const int T = 1000; |
更相减损术
- 若
, - 若
, - 若
, - 若均不满足,设
, 则
1 | int gcd(int a, int b) { |
最小公倍数
定义
一组整数的公倍数,是指同时是这组数中每一个数的倍数的数。0是任意一组整数的公倍数。
一组整数的最小公倍数,是指所有正的公倍数里面,最小的一个数。记作lcm(a,b)
性质
若
,则 若
,则
进而对任意,都有
若
,则
求法
两个数:
代码
1 | ll lcm(ll a,ll b){ |
多个数:我们其实没有必要求一个共同的最大公约数再去处理,最直接的方法就是,当我们算出两个数的 gcd,或许在求多个数的 gcd时候,我们将它放入序列对后面的数继续求解,那么,我们转换一下,直接将最小公倍数放入序列即可。
素数与合数
见质数
算术基本定理
内容
算术基本引理:设p是素数,
唯一分解定理:设正整数a,则必有表示
素数的另一种定义
对整数
同余
定义
设当
性质
定理 1 当
且 时,有 定理 2 当
时,有 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61a + c \equiv b + d \pmod m,\\
a - c \equiv b - d \pmod m,\\
a \times c \equiv b \times d \pmod m.
- **定理 3** 当 $$ac \equiv bd \pmod m\quad\text{且}\quad \gcd(c,m)=1$$ 时,有 $$a \equiv b \pmod m.$$
- **定理 4** 当 $$a \equiv b \pmod m$$ 时,对于任意的 $c\neq0$,有 $$ac \equiv bc \pmod m.$$
- **定理 5** 当 $$a \equiv b \pmod m$$ 时,对于任意的 $k>0$,有 $$a^k \equiv b^k \pmod m.$$
- **定理 6** 当 $$a \equiv b \pmod m$$ 时,对于任意的整数 $t$,有 $$a = b + t\,m.$$
## 同余原理
当需要返回数据很大,超过了longlong的范围,一般需要返回一个数字对另一个数字取模的结果
对于四则运算,位数(bits)固定,我们认为时间复杂度为$O(1)$,但保留中间结果的情况下,位数可能会改变,导致复杂度增加
**定理:对于k位(非32、64位)整数,加减的复杂度为$O(k)$,乘除的复杂度变为$O(k^2)$**
此时需要同余原理
同余的数学化表示:
### 加法同余
对于$(a+b)\bmod{k}=c$,为了避免$a+b$得到更大的位数以出现问题,我们可以分别对$a$和$b$取模再相加取模,即$(a\bmod{k}+b\bmod{k})\bmod{k}=c'$,这样可以把$a$和$b$限制在32或64位,结果$c=c'$
### 乘法同余
对于$(a\times b)\bmod{k}=c$,分别对$a$和$b$取模再相乘取模,即$(a\bmod{k}\times b\bmod{k})\bmod{k}=c'$,这样可以把$a$和$b$限制在32或64位,结果$c=c'$
**注意:要保证相乘时中间结果不能溢出**
### 减法同余
关于取模,若一个数取模后的结果是负数,**则需要加一个模数后取模**,以获得他的正数表示
例如一个数%7的结果是-2,等同于这个数+7后%7的结果5,因为两者加2后分别是0和7,都可以被7整除
对于$(a-b)\bmod{k}=c$,我们需要在分别模m的基础上加一个m,即$((a\bmod{k}-b\bmod{k})+m)\bmod{k}=c'$,为了避免获得负数中间结果
# C/C++的整数除法与取模
## 规定
C/C++规定在整数除法中:
- 除数为0时,行为未定义
- 否则$\frac{a}{b}\times b+a\% b=a$
即取模运算的符号取决于除法如何取整,而这是实现定义的
从C++11起,规定**商向零取整**,取模的符号**与被除数相同**5 % 3 == 2; 5 % -3 == 2; -5 % 3 == -2; -5 % -3 == -2;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
## 快速乘
要求模数在long long范围内的乘法取模,避免整数溢出,可以使用快速乘,能够实现$O(1)$且不需要`int128`
我们可以发现:$a\times b\bmod{m}=a\times b-\lfloor\frac{ab}{m}\rfloor\times m$
使用ull的自然溢出,可得:$a\times b\bmod{m}=a\times b-\lfloor\frac{ab}{m}\rfloor\times m=(a\times b-\lfloor\frac{ab}{m}\rfloor\times m)\bmod{2^{64}}$
对于$\lfloor\frac{ab}{m}\rfloor$,若结果r在$[0,m)$时,直接返回r,否则返回$r+m$
```c++
long long binmul(long long a, long long b, long long m) {
unsigned long long c =
(unsigned long long)a * b -
(unsigned long long)((long double)a / m * b + 0.5L) * m;
if (c < m) return c;
return c + m;
}
数论函数
数论函数指定义域为正整数的函数,可以视为一个数列
积性函数
定义
- 数论中,若函数
满足 ,且 对任意互质的 都成立,则 为积性函数 - 数论中,若函数
满足 ,且 对任意的 都成立,则 为完全积性函数
性质
若
对正整数
若
为积性函数,则
若
为完全积性函数,则
$$ F(x)=_i F(p_i^{k_i}) =_i^{k_i},.$$
加性函数
定义
- 数论中,若函数
满足 ,且 对任意互质的 都成立,则 为积性函数 - 数论中,若函数
满足 ,且 对任意的 都成立,则 为完全积性函数
性质
对正整数
若
为加性函数,则有
若
为完全加性函数,则有