基础数论小结(25.9.23)
基础数论
同余
- 自反性 a ≡ a (mod m)
- 对称性 a ≡ b (mod m),则 b ≡ a (mod m)
- 传递性 a ≡ b (mod m) 且 b ≡ c (mod m) a ≡ c (mod m)
- 加减性 a ≡ b (mod m) 且 c ≡ d (mod m) a±c ≡ b±d (mod m)
- 乘法性 a ≡ b (mod m) 且 c ≡ d (mod m) ac ≡ bd (mod m)
k * a ≡ k * b (mod m)- 乘方性 a ≡ b (mod m) 则 a^n ≡ b^n (mod m)
- 模的缩放 a ≡ b (mod m) 且d是m的约数(d | m), 则 a ≡ b (mod d)
余数性质
余的分配性 (a+b+c+d) % r = { (a%r)+(b%r)+(c%r)+(d%r) }%r
a = x*k1+r ......(a+b+c+d)%r = x(k1+k2+k3+k4) + R = 0 + R%r = { (a%r)+(b%r)+(c%r)+(d%r) }%r
余的分配性(2) (a * b * c * d) % r = {(a%r) * (b%r) * (c%r) * (d%r) }%r
= ( (a%r) * (b%r) ) %r ......涉及除数的式子 (b / c)%m = (b * (c的逆元)) %m
欧几里得
- 我们通过设x为a,b的公约数,可以通过等式发现gcd(a,b) == gcd(b,a%b)
所以我们可以通过此,使用递归,求得答案- 因为除法可能会爆 ll,故我们尝试使用,更相减损术求得答案
- 若2|a 2|b gcd(a,b) = 2gcd(a/2,b/2);
- 2|a或者2|b
gcd的应用
可以知道,两个数之间gcd可以直接logn求取,那么多个数呢
很明显,若求得的gcd,放在数组里继续求并不冲突
所以:gcd(a,b,c) = gcd(gcd(a,b),c)还可以通过设质数的方去得知,gcd(a,b) * lcm(a,b) = a*b
多个数的lcm,也可以通过与gcd同样方法求取
扩展欧几里得
ax + by = gcd(a,b)的递归法求解
通过求式子可以解得:
𝑥1 =𝑦2
𝑦1 =𝑥2 −⌊𝑎/𝑏⌋𝑦2
之后直接通过不断向下递归,直至x=1,y=0(得知了有几层)
向上寻找回代int Exgcd(int a, int b, int &x, int &y) { if (!b) { x = 1; y = 0; return a; } int d = Exgcd(b, a % b, x, y); int t = x; x = y; y = t - (a / b) * y; return d; }
ax + by = gcd(a,b)的迭代法求解
与递归法的式子是不同的
当 𝑥 =1,𝑦 =0
,𝑥1 =0
,𝑦1 =1
时
𝑎𝑥+𝑏𝑦=𝑎
𝑎𝑥1+𝑏𝑦1=𝑏 𝑎𝑥1+𝑏𝑦1=𝑏
𝑎(𝑥−𝑞𝑥1)+𝑏(𝑦−𝑞𝑦1)=𝑎−𝑞𝑏int gcd(int a, int b, int& x, int& y) { x = 1, y = 0; int x1 = 0, y1 = 1, a1 = a, b1 = b; while (b1) { int q = a1 / b1; tie(x, x1) = make_tuple(x1, x - q * x1); tie(y, y1) = make_tuple(y1, y - q * y1); tie(a1, b1) = make_tuple(b1, a1 - q * b1); } return a1; }
拓展欧几里得应用
求模逆元
ax≡1(modm)x 是 𝑎
在模 𝑚
意义下的 逆元
设:ax+my = 1 (gcd(a,m) == 1)
求同余线性方程
ax = b(mod n)
分为两种情况第一种:a,n互质,说明a在模n的意义下有逆元
x = b * (a的逆元)(mod n)
第二种:a,n不互质,
gcd (a,n) = d
考虑两种情形:
当 𝑑 不能整除 𝑏 时,方程无解
当可以整除时,将a,b,n都除b
𝑎′𝑥≡𝑏′(mod𝑛′)gcd(a' , n') = 1
解得d = gcd(a,n)
总答案数 = d
其过程证明主要为:a(x' + 𝑘𝑛′)%n = b%n
然后证明 在k<d-1时,总共有d个解 x = x' + kn'