唯一分解定理 & 分解质因数
任何一个正整数 n>1 都可以唯一地分解为一组质数的乘积, n=Πinfk=1pekk
证明
数学归纳法, 如果一个小于 N 的自然数都符合, 那么讲 N 分解成任意两个数的乘积, 再将表示法合并起来 (显然所有质数和 4 都符合)
- [2,n] 内的质数个数大约为 nlog(n)
- 约数个数方案数 (e1+1)(e2+1)....(ek+1)
- 约数和 (1+p11+p21+...+pe11)(1+p12+p22+...+pe22)....
计算方法都可以用 分解质因数 考虑, 于是这样可以把一个数 N 拆成若干个独立的部分
互质 & GCD & LCM
如果 gcd(a,b)=1 , 则 a 和 b 互质, 也就是说他们没有共同的质因数
gcd(a,b)=gcd(a−b,b)=gcd(a+b,b)
gcd(na,nb)=n×gcd(a,b)
gcd(a,b)=a×blcm(a,b)
对于一个质因数 pi, 如果在 a 中出现了 ea 次, 在 b 中出现了 eb 次, 则该质因数在 gcd 中出现 min(ea,eb) 次, 在 lcm 出现 max(ea,eb) 次
整除
- 如果 a|b 并且 b|c , 那么 a|c
- 如果 a|b 且 a|c , 对于任意整数 x,y , 有 a|(bx+cy)
- m≠0 且 a|b 等价于 am|bm
- ax+by=1,a|n,b|n, 那么 ab|n
- b=q×d+c , 那么 d|b 的充要条件是 d|c
- 若 2 能整除 a 的最末位 ( 0 可以被任何数整除), 则 2|a, 若 4 能整除 a 的最后 2 位 , 则 4|a , 若 2 能整除 a 的最后 3 位 , 则 8|a...
- 若 x×a≡y×b(modn) , 则 x×a≡y×b+n×p+n×q+...(modn)
- 若 3 能整除 a 的各位数字之和, 则 3|a , 若 9 能整除 a 的各位数字之和则 9|a
同余
a≡b(modm) 意味着 a−b=m×k
- 自反性 a≡a(modm)
- 对称性 若 a≡b(modm) , 则 b≡a(modm)
- 传递性 若 a≡b(modm) , b≡c(modm) , 则 a≡c(modm)
- 同加性 若 a≡b(modm) , 则 a+c≡b+c(modm)
- 同乘性 若 a≡b(modm) , 则 a×c≡b×c(modm)
- 同幂性 若 a≡b(modm) , 则 an≡bn(modm)
- 循环性 对于 axmodm, 构造出无限长的 x 序列, 发现必定存在一个小于 m 的循环节, 所以如果一个数出现 k 次, 循环节必定循环了 k 次
- 推论 若 amodp=x,amodq=x,(p,q) 互质, 则 amod(p×q)=x
Miller_Rabin素性测试
常规判定素数方法: 从 1至√n 中枚举 p ,判断 p|n
Miller_Rabin
对于一个 n ,假如它是质数
设 n−1=d×2r , 其中 d 是一个奇数
对于每一个 1≤a<n 对于下面两种条件,至少有一个是成立的
- ad≡1(modn)
- 存在 0≤i<r , 满足 ad×2i≡n−1(modn)
于是当前对于 1≤a<n
- 满足至少一个条件 --> n 可能是质数
- 两个条件都不满足 --> n 一定不是质数
于是可以寻找对个 a 对 n 进行检测, 如果全部通过检测有极大概率 n 为质数
| bool miller_rabin(int n, int a) { |
| int d = n - 1, r = 0; |
| while (!(d & 1)) |
| d >>= 1, r++; |
| int x = ksm(a, d, n); |
| if (x == 1) return true; |
| for (int i = 0; i < r; i++) { |
| if (x == n - 1) return true; |
| x = 1ll * x * x % n; |
| } |
| return false; |
| } |
| |
| bool prime(int n) { |
| if (n < 2) return false; |
| int prime_list[10] = {2, 3, 5, 11, 17, 19, 23, 37, 41, 43}; |
| for (int a = 0; a < 10; a++) { |
| if (n == prime_list[a]) return true; |
| if (!miller_rabin(n, prime_list[a])) return false; |
| } |
| return true; |
| } |
逆元
如果 gcd(a,m)=1 且存在唯一的 b 存在 a×b≡1(modm) 且 1≤b<m, b 为 a 在模 m 意义下的逆元
费马小定理
ap−1≡1(modp)(p为素数,gcd(a,p)=1)
欧拉定理
aϕ(m)≡1(modm)(gcd(a,m)=1)
扩展欧拉定理
- c<ϕ(m) 则 ac≡ac(modm)
- c≥ϕ(m) 则 ac≡a[cmodϕ(m)]+ϕ(m)(modm)
线性求逆元
ap−1≡1(modp)(gcd(a,p)=1)
mmoda=m−a×⌊ma⌋
设 b=mmoda
a−1≡a−1×b×b−1=a−1×(m−a×⌊ma⌋)×b−1(modm)
得 a−1≡−⌊ma⌋×b−1(modm)
扩展欧几里得
裴蜀定理
对于两个整数 a,b, 一定存在一组解使得 ax+by=gcd(a,b)
求出不定方程 ax+by=gcd(a,b) 的一组特解
ax+by=gcd(a,b)
ax+by=gcd(b,amodb)
bx+(a−⌊ab⌋×b)y=gcd(b,amodb)
ay+b(x−⌊ab⌋×y)=gcd(b,amodb)
边界情况
当 b=0 时 , x=1,y=0
| int exgcd(int a, int b, int &x, int &y) { |
| if (b == 0) { |
| x = 1; y = 0; |
| return ; |
| } |
| int d = exgcd(b, a % b, x, y); |
| int tmp = x; |
| x = y; |
| y = tmp - (a / b) * y; |
| } |
通解公式
x=x0+bgcd(a,b)×t,y=y0−agcd(a,b)×t
求出不定方程 ax+by=c 的一组特解
根据 裴蜀定理 判断是否 gcd(a,b)|c
然后求出 ax+by=gcd(a,b) 的一组特解 (x0,y0)
x0=x0×cgcd(a,b),y0=y0×cgcd(a,b)
通解公式
x=x0+bgcd(a,b)×t,y=y0−agcd(a,b)×t
扩展欧几里得 一般用于解 同余方程 a×x≡c(modm)
原根
定义
在模 m 的意义下, 算出 a1,a2,a3...aϕ(m), 如果这些数两两互不相等, 则 a 为模 m 意义下的原根
给定一个 m 找到一个在模 m 意义下的原根 a
发现一个数 m 存在原根只可能是 2,4,pa,2pa , 又发现原根 a 一定 ≤10, 于是可以暴力判断check
优化
check的时候发现对于 ai=aj(i<j) 必定会存在 ak=1(k=j−i), 发现 k 只可能是 k|ϕ(m) (可以用欧拉定理和循环节考虑), 于是可以 √m 求解
| bool check(int m, int a) { |
| int phi = get_phi(m); |
| for (int i = 2; i <= sqrt(phi); i++) { |
| if (phi % i == 0) { |
| if (ksm(a, i, m) == 1) return false; |
| if (ksm(a, m / i, m) == 1) return false; |
| } |
| } |
| return true; |
| } |
| |
| int get_yg(int m) { |
| for (int i = 1; i; i++) { |
| if (check(m, i)) return i; |
| } |
| } |
BSGS
求 ax≡b(modp) 的一个解, p≤109且是质数
朴素求法
枚举 x, 由于极限情况是原根, 也就是循环节长度最多为 p−1 , 则 1≤x<p−1, 判断即可
BSGS
令 S=√p, 列出矩阵
⎛⎜⎝a0a1a2...aS−1aSaS+1aS+2...a2S−1...............⎞⎟⎠
将第一行的值保存下来 ( 可用 sort+binary,set,hash ), 对于每一行暴力判断 b 有没有出现在这一行, 对于 1≤i≤n, 只需查找 b×a−(i−1)×S 是否在第一行出现过就行了
思想类似于分块, 复杂度 hash:√p, 非 hash√p×log(p)
| int bsgs(int a, int b, int p) { |
| int s = sqrt(p); |
| set<int> se; |
| int v = 1; |
| for (int i = 0; i < s; i++) { |
| if (v == b) return i; |
| se.insert(v); |
| v = 1ll * v * a % p; |
| } |
| for (int i = 1; i <= s; i++) { |
| int v = 1ll * b * ksm(ksm(a, i * s, p), p - 2, p) % p; |
| if (s.count(v) != 0) { |
| int v = ksm(a, i * s, p); |
| for (int j = i * s; j; j++) { |
| if (v == b) return j; |
| v = 1ll * v * a % p; |
| } |
| } |
| } |
| } |
欧拉函数
ϕ(x):[1,x]内与x互质的数的个数
性质 : ϕ(a×b)=ϕ(a)×ϕ(b)(gcd(a,b)=1)
设 x=Πpeii , 则 ϕ(x)=x×Π(1−1pi)
证
ϕ(pk)=pk−pk−1
ϕ(x)=Πϕ(peii)=Πpki−pk−1i=x×Π(1−p−1i)
积性函数
f(a×b)=f(a)×f(b)(gcd(a,b)=1)
- f(x)=Πf(peii)
完全积性函数
f(a×b)=f(a)×f(b)
- f(x)=Πf(pi)ei
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】