算法模板 SFMB.XYZ

全网最好的ACM/ICPC零基础算法模板,代码简短,封装完美,解释清晰,通用性强。

只包含常用算法,适合 Rating 1200 ~ 2000 。

版本

By dqw ,Version 4.0 - 2025.3.15

许可

CC BY 4.0 允许任何形式的使用、复制、修改、合并、转载

Copyright © 2025 dqw. All rights reserved.

资源

官方在线网页版(https://sfmb.xyz

下载纸质版 PDF 文件(TBC)(不要直接打印此网页)

目录

算法模板 SFMB.XYZ全网最好的ACM/ICPC零基础算法模板,代码简短,封装完美,解释清晰,通用性强。只包含常用算法,适合 Rating 1200 ~ 2000 。版本许可资源目录i. 初始化1. Vim for Linux 快速配置2. C++ 初始文件3. C++ 火车头编译优化4. 随机数生成 64 位随机数(初始文件默认已包含)卡时自定义 unordered_map/unordered_set 防卡哈希ii. 数论1. 快速幂2. 快速平方根3. 扩展欧几里得4. 逆元与组合数扩展欧几里得求单个数字的逆元线性求逆元和组合数5. 素数测试与因式分解Miller Rabin 判断素数Pollard Rho 分解因数6. 欧拉筛法7. 扩展中国剩余定理8. 数论分块iii. 数据结构1. 并查集 DSU2. ST 表3. 树状数组单点修改,区间求和 求逆序对二维树状数组4. 线段树普通线段树 单点修改,区间查询懒标记线段树 区间加,区间乘,区间赋值,区间求和5. 莫队iv. 图论1. 最短路2. 树的直径3. 最近公共祖先 LCA4. 拓扑排序5. 最小生成树 MSTPrimKruskal6. 二分图v. 字符串1. 字符串哈希 String Hash2. 前缀函数 KMP3. Z 函数 拓展 KMP4. 最长回文串 Manacher5. 后缀数组 SA6. 字典树 Trie字符串字典树0-1 字典树7. Lyndon 分解8. 最小表示法9. AC 自动机 Aho-Corasickvi. 动态规划1. 最长上升子序列 LIS2. 最长公共子序列 LCS3. 最长公共上升子序列 LCISvii. 几何1. 二维计算几何基础2. 多边形的周长与面积Pick 定理多边形求周长三角形求有向面积多边形求有向面积3. 凸包Andrew 算法 求凸包闵可夫斯基和 判断点是否在凸包中4. 旋转卡壳 —— 求凸包直径viii. 代数1. 快速傅里叶变换 FFT2. 快速数论变换 NTT3. 行列式高斯消元行列式求值4. 矩阵

i. 初始化

1. Vim for Linux 快速配置

2. C++ 初始文件

3. C++ 火车头编译优化

4. 随机数

生成 64 位随机数(初始文件默认已包含)

卡时

自定义 unordered_map/unordered_set 防卡哈希

ii. 数论

1. 快速幂

2. 快速平方根

3. 扩展欧几里得

4. 逆元与组合数

扩展欧几里得求单个数字的逆元

线性求逆元和组合数

5. 素数测试与因式分解

Miller Rabin 判断素数

Pollard Rho 分解因数

前置:Miller Rabin 判断素数(isprime

6. 欧拉筛法

7. 扩展中国剩余定理

前置:扩展欧几里得(exgcd

8. 数论分块

iii. 数据结构

1. 并查集 DSU

2. ST 表

3. 树状数组

单点修改,区间求和 求逆序对

二维树状数组

4. 线段树

普通线段树 单点修改,区间查询

懒标记线段树 区间加,区间乘,区间赋值,区间求和

5. 莫队

假设 n=m,那么对于序列上的区间询问问题,如果从 [l,r] 的答案能够 O(1) 扩展到 [l1,r],[l+1,r],[l,r+1],[l,r1](即与 [l,r] 相邻的区间)的答案,那么可以在 O(nn) 的复杂度内求出所有询问的答案。离线。

iv. 图论

1. 最短路

2. 树的直径

树上任意两节点之间最长的简单路径即为树的直径

3. 最近公共祖先 LCA

给定一棵有根树,求出指定两个点直接最近的公共祖先,倍增算法求 LCA

4. 拓扑排序

给一个有向无环图的所有节点排序

5. 最小生成树 MST

无向连通图的最小生成树为边权和最小的生成树。Prim 在稠密图中比 Kruskal 优,在稀疏图中比 Kruskal 劣。

Prim

Kruskal

前置:并查集(DSU

6. 二分图

给定一个二分图 G,即分左右两部分,其左部点的个数为 n,右部点的个数为 m,边数为 k,各部分之间的点没有边连接,要求选出一些边,使得这些边没有公共顶点,且边的数量最大。

v. 字符串

1. 字符串哈希 String Hash

2. 前缀函数 KMP

给定一个长度为 n 的字符串 s,其 前缀函数 被定义为一个长度为 n 的数组 π。其中 π[i] 是:子串 s[0i] 最长的相等的真前缀与真后缀的长度。特别地,规定 π[0]=0

3. Z 函数 拓展 KMP

对于一个长度为 n 的字符串 s,定义函数 z[i] 表示 ss[i,n1](即以 s[i] 开头的后缀)的最长公共前缀(LCP)的长度,则 z 被称为 sZ 函数。特别地,z[0]=n

4. 最长回文串 Manacher

对于每个位置 i=0n1,设值 d1[i]d2[i] 分别表示以位置 i 为中心的长度为奇数的回文串个数(最长回文串的半径长度) 和 以位置 i1i 之间为中心长度为偶数的回文串个数(最长回文串的半径长度)

5. 后缀数组 SA

把字符串 S 的所有后缀按照字典序排列,排名为 i 的后缀记为 sa[i]

额外地,我们考虑排名为 i 的后缀与排名为 i1 的后缀,把二者的最长公共前缀的长度记为 height[i] ,规定 height[0]=0

6. 字典树 Trie

字符串字典树

0-1 字典树

7. Lyndon 分解

定义一个串是 Lyndon 串,当且仅当这个串的最小后缀就是这个串本身。

Duval 算法 Lyndon 分解:串 s 的 Lyndon 分解记为 s=w1w2wk,其中所有 wi 为简单串,并且他们的字典序按照非严格单减排序,即 w1w2wk。可以发现,这样的分解存在且唯一。

8. 最小表示法

字符串 S 的最小表示为与 S 循环同构的所有字符串中字典序最小的字符串。

9. AC 自动机 Aho-Corasick

给你一个文本串 Sn 个模式串 T1n,请你分别求出每个模式串 TiS 中出现的次数。AC 开始时已初始化且只能处理一次。

vi. 动态规划

1. 最长上升子序列 LIS

2. 最长公共子序列 LCS

当且仅当 ab 都是排列且长度相等时可使用此方法

前置:最长上升子序列(LIS

3. 最长公共上升子序列 LCIS

vii. 几何

1. 二维计算几何基础

这里的 Z 是用于坐标的某种类型,通常是 int(已定义为 long long),doublelong double

point 类型可以和 point 类型进行加减运算,和 Z 类型进行乘除运算。

2. 多边形的周长与面积

前置:二维计算几何基础(point

Pick 定理

平面上以整点为顶点的简单多边形的面积 = 边上的点数 / 2 + 内部的点数 - 1 。

多边形求周长

三角形求有向面积

多边形求有向面积

3. 凸包

前置:二维计算几何基础(point

凸多边形:凸多边形是指所有内角大小都在 [0,π] 范围内的 简单多边形

凸包:在平面上能包含所有给定点的周长最小的凸多边形叫做凸包。

Andrew 算法 求凸包

闵可夫斯基和 判断点是否在凸包中

现在有两个凸包 P,Q,平移 qQ,问每次移动后两凸包是否有交点。

4. 旋转卡壳 —— 求凸包直径

前置:二维计算几何基础(point

凸包直径,即凸包上各点的平面最远点对的距离。

viii. 代数

给定一个 n 次多项式 F(x)(长度 n+1),和一个 m 次多项式 G(x)(长度 m+1),系数从低到高。

请求出 F(x)G(x) 的卷积(从低到高表示 F(x)G(x) 的系数)。

1. 快速傅里叶变换 FFT

2. 快速数论变换 NTT

前置:快速幂(qpow

模数意义下求卷积,模数只能为 998244353

3. 行列式

高斯消元

给定一个线性方程组,对其求解。

{a1,1x1+a1,2x2++a1,nxn=b1a2,1x1+a2,2x2++a2,nxn=b2an,1x1+an,2x2++an,nxn=bn

行列式求值

给定一个 n 阶行列式 A,求 |A|

4. 矩阵