

基础数论的一些知识
一些基本数论相关的知识。
逆元(inverse)
若 b 是 a关于 m 的逆元则有: ab \equiv 1 \pmod m ,即 (ab) \bmod m = 1 。
应用
求解 (a/b) \bmod m :
设 c 为 b 关于 m 的逆元,即有: (bc) \bmod m = 1 。
那么 (a/b) \bmod m = (a/b*1) \bmod m = ((a/b) * (bc)) \bmod m = (a*c) \bmod m
即:a 除以 b 取模等价于 a 乘以 b 的逆元取模。
求解
扩展欧几里得
若 b 是 a 关于 m 的逆元则有: ab \equiv 1 \pmod m 。
等价于存在 k 使得 k*m + 1 = ab ,即求解 km - ab = 1 中的 b,由于 a 和 m 已知,可将 b 和 k 看成未知数,问题转化为求解线性方程: mx - ay = 1 ,可以使用扩展欧几里得算法( exgcd )求解。
同时我们通过扩展欧几里得算法的限制知道:若 a 和 m 不互质(\gcd (a, m) \neq 1),则不存在 a 关于 m 的逆元。
ll extend_gcd(ll a, ll b, ll &x, ll &y)
{
if (b == 0)
{
x = 1, y = 0;
return a;
}
else
{
ll r = extend_gcd(b, a % b, y, x);
y -= x * (a / b);
return r;
}
}
ll inv(ll a, ll n)
{
ll x, y;
extend_gcd(a, n, x, y);
x = (x % n + n) % n;
return x;
}
费马小定理
由费马小定理可知: x^{p-1} \equiv 1 \pmod p ,则有: x * x ^{p-2} \equiv 1 \pmod p 。
即 x 的逆元是 x^{p-2}。
注意 x 和 p 必须互质。
const int mod = 1000000009;
long long quickpow(long long a, long long b)
{
if (b < 0) return 0;
long long ret = 1;
a %= mod;
while(b)
{
if (b & 1) ret = (ret * a) % mod;
b >>= 1;
a = (a * a) % mod;
}
return ret;
}
long long inv(long long a)
{
return quickpow(a, mod - 2);
}
线性逆元筛
const int mod = 1000000009;
const int maxn = 10005;
int inv[maxn];
inv[1] = 1;
for(int i = 2; i < 10000; i++)
inv[i] = inv[mod % i] * (mod - mod / i) % mod;
求阶乘的逆元
const int mod = 1000000009;
const int maxn = 10005;
int inv[maxn];
inv[1] = 1;
for(int i = 2; i < 10000; i++)
inv[i] = inv[mod % i] * (mod - mod / i) % mod;
快速求组合数
如果需要快速求出模 P 意义下的 C_{n}^{m} (n,m < N),可以先线性复杂度求出 1 到 n 阶乘的逆元,然后套用组合数公式即可求出
C_{n}^{m} \% P = inv[fact(n)] * inv[fact(m)] * inv[fact[n-m]]
欧拉定理
欧拉函数
\phi(n)表示小于等于 n 的正整数之中,有多少个与n构成互质关系。
分类讨论
- n = 1, 则\phi(n) = 1
- n 为质数,则 \phi(n) = n - 1
- n 为质数的某个幂,即 n = p ^ k (p为质数),则 \phi(n) = p^k - p^{k-1}
- n 为两个互质的整数之积,即 n = p_1 \times p_2 ,则 \phi(n) = \phi(p_1p_2) = \phi(p_1) \phi(p_2)
- n 分解为若干个质数的幂 ,即 n = p_1^{c1} p_2^{c2} p_3^{c3}…p_n^{cn} ,则根据4可知 \phi(n) = n(1-\frac{1}{p1})(1-\frac{1}{p2})(1-\frac{1}{p3})…(1-\frac{1}{pr})
欧拉定理
如果两个正整数a,n互质,则n的欧拉函数满足以下等式:
a^{\phi(n)} \equiv 1 \pmod n
费马小定理
如果a和质数p互质,因为\phi(p) = p - 1,则有
a^{p-1} \equiv 1 \pmod p
RSA
秘钥生成过程
- 随机选择两个不相等的质数p和q
- 计算p和q的乘积n,n的二进制位数被称为秘钥的长度
- 计算n的欧拉函数\phi(n) = (p-1)(q-1)
- 随机选择整数e,1 < e < \phi(n),且e与\phi(n)互质
- 计算e对于\phi(n)的逆元d,即ed \equiv 1 \pmod {\phi(n)}
- 其中公钥为(n, e),私钥为(n, d)
加密与解密过程
对于小于n的整数m,加密为:
c = m^e \mod n
m为需要加密的信息,e为公钥,c为加密后的密文。
m = c^d \mod n
d为私钥。
Miller-Rabin 素性检测
Miller-Rabin 算法是一种判断一个数是否为质数的算法。
算法主要基于两个事实
- 费马小定理,即对于任意质数p以及 p\nmid a ,有 a^{p-1}\equiv 1(\bmod p)
- 对于质数 p ,x^2\equiv 1(\bmod p) 有且只有平凡解 x\equiv \pm 1(\bmod p)
算法的伪代码如下
Input #1: n > 3, an odd integer to be tested for primality;
Input #2: k, a parameter that determines the accuracy of the test
Output: composite if n is composite, otherwise probably prime
write n − 1 as (2^r)·d with d odd by factoring powers of 2 from n − 1
WitnessLoop: repeat k times:
pick a random integer a in the range [2, n − 2]
x ← (a^d) mod n
if x = 1 or x = n − 1 then
continue WitnessLoop
repeat r − 1 times:
x ← (x^2) mod n
if x = 1 then
return composite
if x = n − 1 then
continue WitnessLoop
return composite
return probably prime
可以证明,上述代码的正确率至少为 1-2^{-k},即尝试的次数 k 越多,出错概率越小(出错概率即把合数误判成质数的概率)。
多项式
快速傅里叶变换(FFT)
欧拉公式: e^{i\theta} = \cos \theta + i \sin \theta