同余系简述
by Acc_Robin
基础知识
带余除法
对整数 存在 唯一 一对 使得 , 称为余数。
下取整
对 ,,称
常用性质
- 当 , 有不超过 种取值。
证明
在 时,显然不超过 种;在 时,,也不超过 种。
证明
对右侧进行带余除法:
对左侧进行带余除法:
因为 ,且带余除法具有唯一性得证。
- 由上面两条可知, 无论怎么除,都在 这个集合内,且集合大小不超过 。
最大公约数与最小公倍数
对 ,都有 ,称 为 的最大公约数,记作 。
对 ,都有 ,称 为 的最小公倍数,记作 。
常用性质
-
,。
-
辗转相除法:,特例 。
-
使用辗转相除法计算 的复杂度为 。
??? note"证明"
只需证明 。
当 时结论显然;当 时 。
-
。
-
(多个时不适用)。
-
本质上是每个质数指数取 ,而 是取 。 是求质因子的交集,而 是求并集。
-
裴蜀定理:一定存在一对整数 使得 ,且 是最小的由 生成的非负整数,反之也成立。
同余系
定义 若 ,则称 模 同余,记作 。
同余系就是 中所有整数,和 运算组成的群。
逆元
定义数 在模 意义下的乘法逆元为使得 的 。
存在逆元的充要条件是 。
求逆元的方法
-
求单个数逆元:在模数是质数时使用费马小定理。
-
求多个数逆元(比如 ):维护前缀积,再反过来推一边(注意特判 )。
-
求单个数逆元但模数不是质数时:使用 exgcd。
exgcd
由裴蜀定理,一定存在 使得
因为上式需恒成立成立,则有
解之即得
类似 以此向下递归计算即可,复杂度同样是 。
本质是在求解一个同余方程组 。
欧拉定理
欧拉函数
定义 表示 中与 互质的数的个数。
常用性质
-
定义:。
-
积性函数:
-
若 (标准素因数分解),则 。
证明
求补集,即 中含 的素因子的数的个数,相当于对 的每个素因数有限制再求并。
对于素因子集合 , 中是这个集合所有数的倍数的个数为 ,并且有容斥系数 。那么最终答案为
-
若 ,则 。
-
,也即 。
-
在嵌套 次后变为 。
证明
若 是 则结束;否则若 是偶数,因为会有一个 变成 ,所以;否则若 是奇数,则必然有一个奇质因子变为偶数。
求欧拉函数的方法
-
按照解析式直接求解,复杂度 。
-
在可以 预处理时并且多次询问时,维护最小质因子进行分解,复杂度 。
-
埃氏筛:,复杂度 或 。
-
线性筛:
欧拉定理
证明
扩展欧拉定理
理解:互质时为普通欧拉定理,否则会有 形循环节。
用途:可以用来求“幂塔”:,不断套用扩展欧拉定理,在 次后指数的模数就会变成 。
中国剩余定理(CRT)
求解同余方程组
其中 两两互质。
考虑两两合并:
我们希望 时显示 , 时显示 ,那么就让 ,但此时显示的是 和 ,那就分别乘上 在模 下的逆元 和 在模 下的逆元即可。合并完的方程模数是 。
因为两两互质,所以一定存在逆元。
| auto CRT = [](int n, const vector<int>& a, const vector<int>& p) {
ll r = 0, m = 1, M, x, y;
for (int i = 0; i < n; ++i, m = M) {
M = m * p[i], exgcd(p[i], m, x, y);
x = (x % m + m) % m, y = (y % p[i] + p[i]) % p[i];
r = (r * x % M * p[i] + a[i] * y % M * m) % M;
}
return r;
};
|
扩展中国剩余定理(EXCRT)
当 不互质时,不能够直接构造逆元。第一个方程有通解 ,第二个方程有通解 ,令这二者相等即 ,形似裴蜀定理。
那么有解的条件就是 ,并且使用 exgcd 求得一组合法 即可。此时合并完方程的模数是 。
注意防止溢出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | auto mul = [](ll a, ll b, ll m) {
ll c = a * b - ll((long double)a / m * b + 0.5L) * m;
return c < 0 ? c + m : c;
};
auto exCRT = [](int n, const vector<ll>& a, const vector<ll>& p) {
ll r = 0, m = 1, M, x, y, d;
for (int i = 0; i < n; ++i, m = M) {
d = exgcd(m, p[i], x, y), M = p[i] / d * m;
y = (a[i] - r % p[i] + p[i]) % p[i];
if (y % d) return -1ll;
x = mul(x, y / d, p[i]), r = (r + mul(x, m, M)) % M;
}
return r;
};
|
Lucas 定理
在 是素数时,有
重要性质
Krummer 定理
中 的指数 进制下 做加法时的进位次数。
证明
显然有勒让德定理 。
又因为 ,所以 。
当且仅当第 位产生进位才不会被除掉。
exLucas
对 时,求 (事实上所谓 exLucas 和 Lucas 没有关系,只是一种求组合数的技巧,而其功能和 Lucas 互补而得名)。
对 素因数分解后使用 CRT 合并即可,现在处理 时的答案。
首先有 ;定义 ,相当于 去掉所有 后剩下的数。后文分别简记为 和 。
所求为
发现 可以在 的时间内计算,现在只需要计算 即可。
我们把 拆成两部分,一部分是 的倍数(红色,要被除掉),另一部分是剩下的数(紫色)。
先考虑紫色部分,事实上是由两部分组成的,相当于若干个长度为 的块和最后一个散块:
在对 取模时上式具有周期性,所以只需要预处理除 中非 的倍数的数的前缀积即可 计算上式。
再考虑红色部分,这部分含有 ,是要除以 的
又因为
所以
递归计算 即可。
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 | int z, P, fc[N];
auto qp = [](int a, ll b, int P) {
int z = 1;
while (b) {
if (b & 1) z = 1ll * z * a % P;
a = 1ll * a * a % P, b >>= 1;
}
return z;
};
void exgcd(int a, int b, int& x, int& y) {
if (b == 0) return x = 1, y = 0, void();
exgcd(b, a % b, y, x), y -= a /b * x;
}
auto inv = [](int a, int P) {
int x, y; exgcd(a, P, x, y);
return (x % P + P) % P;
};
auto v = [](int p, ll n) {
ll z = 0;
while (n) z += (n /= p);
return z;
};
int r(ll n, int p, int P) {
if (n == 0) return 1;
ll z = qp(fc[P - 1], n / P, P);
z = 1ll * z * fc[n % P] % P;
return 1ll * z * r(n / p, p, P) % P;
};
auto C = [](ll n, ll m, int p, int P) {
int z = v(p, n) - v(p, m) - v(p, n - m);
z = qp(p, z, P), *fc = 1;
for (int i = 1; i < P; ++i) {
if (i % p == 0) fc[i] = fc[i - 1];
else fc[i] = 1ll * fc[i - 1] * i % P;
}
z = 1ll * z * r(n, p, P) % P;
z = 1ll * z * inv(r(m, p, P), P) % P;
z = 1ll * z * inv(r(n - m, p, P), P) % P;
return z;
};
auto CRT = [](int a, int p) {
int x, y, M = P * p;
exgcd(P, p, x, y);
x = (x % p + p) % p, y = (y % P + P) % P;
z = (1ll * z * p % M * y + 1ll * a * P % M * x) % M;
P = M;
};
auto exLucas = [](ll n, ll m, int p) {
z = 0, P = 1;
int i = 2, j;
for (; i * i <= p; ++i) {
if (p % i == 0) {
j = 1;
while (p % i == 0) p /= i, j *= i;
CRT(C(n, m, i, j), j);
}
}
if (p > 1) CRT(C(n, m, p, p), p);
return z;
};
|
build本页面最近更新:,更新历史
edit发现错误?想一起完善? 在 GitHub 上编辑此页!
people本页面贡献者:AFOI-wiki
copyright本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用