算法模板集合
算法模板集合
[toc]
编译
shell
1 | g++ name.cpp -Wall -Wextra --std=c++17 -o name; .\name.out |
对拍
python
1 | import os |
测时间
cpp
1 |
|
DEBUG
- 数组最大范围
- long long 溢出
- 语句逻辑顺序,定义顺序
- 初始化
- 非法的转移 (从f[i-1]没判断边界)
- 特殊值,n=1,0
- 阅读题意
- for变量正确
VSCODE 代码片段
json
1 | { |
计算几何
cpp
1 | const double eps = 1e-13; |
圆
cpp
1 | struct Circle { |
排序极角
cpp
1 | ll Cross(Vector a, Vector b) { return a.x*b.y - a.y*b.x; } |
读入优化
编译优化
cpp
1 |
cin优化
cpp
1 | ios_base::sync_with_stdio(0); cin.tie(0); |
快读快写
cpp
1 | inline int read() { |
多个测试数据
以EOF结尾
cpp
1 | while (cin >> n) { |
以0结尾
cpp
1 | while ((cin >> n) && n) { |
给定数据组数
cpp
1 | int T; cin >> T; |
STL
struct
cpp
1 | struct Node { |
sort
cpp
1 | sort(A+1, A+n+1); // sort for array in [1,n] from small to big |
vector
cpp
1 | vector<int> A(n+1); // set a vector of index [0,n], init with 0 |
map
cpp
1 | map<pair<int,int>, int> M; // O(logn) |
set
cpp
1 | set<int> s; |
bitset
cpp
1 | bitset<maxn> s; |
pbds
cpp
1 |
|
模拟
初始化
cpp
1 | memset(A, 0, sizeof(A)); // 初始化成0 |
蛇形矩阵遍历
cpp
1 | for (int i = 1;i <= n; ++i) { |
二分
cpp
1 | L = 1; R = n-1; |
离散化去重
离散化去重
cpp
1 | sort(B+1, B+n+1); // 所有数据堆在B里 |
离散化
cpp
1 | typedef int Tl; |
去重(堆在一起)
cpp
1 | sort(A.begin(), A.end()); |
字符串转换
cpp
1 | string tostr(ll x) { |
离散前缀和
cpp
1 | vector<pair<int,ll>> A, B; |
数学
向上/向下取整
cpp
1 | ll up(ll a, ll b) { |
随机数
cpp
1 | template <class T> |
取模结构体
cpp
1 | const int MOD = 1e9 + 7; |
取模
cpp
1 | inline ll add(ll a, ll b) { // 带减法 |
快速幂/龟速乘
cpp
1 |
|
特殊余数
cpp
1 | ll mul(ll a, ll b, ll mod = MOD) { |
费尔马小定理求逆元
cpp
1 | ll fpow(ll a, ll n) { |
O(n)求n个逆元
cpp
1 | inv[1] = 1; |
阶乘与阶乘的逆元
cpp
1 | // 逆元数组大小开够 |
求组合数
cpp
1 | // 需要逆元数组,费马尔小定理求逆元 |
求大组合数
cpp
1 | ll c(int n, int k) { |
周期计数
求
cpp
1 | ll numofperiod(ll R, ll x, ll t) { |
扩展欧几里得exgcd
解决
cpp
1 | void exgcd(ll a, ll b, ll& d, ll& x, ll& y) { |
同余方程
解决
cpp
1 | void exgcd(ll a, ll b, ll& d, ll& x, ll& y) { |
非负情况
cpp
1 | void exgcd(ll a, ll b, ll& d, ll& x, ll& y) { |
欧拉函数
cpp
1 | int phi(int n){ |
E氏筛法
cpp
1 | for (int i = 2;i < maxn; ++i) if (!cnt[i]) |
线性筛/分解质因数
cpp
1 | struct Prime { |
低常数
cpp
1 | struct Prime { |
所有因子
cpp
1 | vector<int> factors(int x) { |
单个质因数分解
cpp
1 | vector<pair<ll,int>> factorize(ll x) { |
数论分块
cpp
1 | for (ll l = 1, r = 0; l <= n; l = r+1) { |
素数测试Miller-Rabin
cpp
1 | ll fpow(ll a, ll n, ll p) { |
Pollard Rho找一个因子, 分解质因数
需要 Miller-Rabin
cpp
1 | template <class T> |
扩展中国剩余定理EXCRT
cpp
1 | void exgcd(ll a, ll b, ll& d, ll& x, ll& y) { |
快速傅里叶变换FFT
cpp
1 | typedef double ld; |
快速数论变换NTT
cpp
1 | const ll MOD = 4179340454199820289; |
线性代数
矩阵快速幂
cpp
1 | const ll MOD = 1e9 + 7; |
矩阵求逆(取模)
cpp
1 | ll fpow(ll a, ll n) { |
线性基
cpp
1 | for (int i = 1;i <= n; ++i) { |
高斯消元(老)
cpp
1 | namespace PG { // projective geometry |
动态规划
最长不下降子序列
cpp
1 | int low[maxn]; |
最长公共子序列
cpp
1 | int M[maxn], low[maxn]; |
DAG最长路
cpp
1 | ll n, m, dp[maxn], book[maxn]; |
树形dp
cpp
1 | // 01状态dp:没有上司的舞会 |
树形背包(简单版)
cpp
1 | void dfs(int x) { |
树形背包( )
cpp
1 |
|
树形背包(DFS序)
cpp
1 | void dfs(int i) { |
状态压缩位运算
cpp
1 | int seti(int mask, int i) { |
计算二进制中
cpp
1 | __builtin_popcount(x) |
数位dp
cpp
1 | int A[20]; |
双边界
cpp
1 | ll tl = l; |
SOS DP
cpp
1 | for(int i = 0; i<(1<<N); ++i) |
Convexhull Trick
cpp
1 | struct ConvexHullTrick { |
Changeroot
cpp
1 | struct Node { |
数据结构
差分数组
cpp
1 | template<typename T> |
单调队列求区间最值
cpp
1 | n = read(); m = read(); |
单调栈求右边下一个比自己大的位置
cpp
1 | stack<pii> s; // type <int,int> arr: A[i] |
MinMaxQueue
cpp
1 | struct MinMaxStack { |
PropertyQueue
cpp
1 | struct PropertyQueue { |
单栈队列
cpp
1 | struct dsqueue { |
双指针
小的可以那么大的也可以
cpp
1 | int r = 0; |
大的可以那么小的也可以
cpp
1 | int r = 0; |
RMQ/ST表
cpp
1 | template<class It,class Func,class T=typename iterator_traits<It>::value_type> |
01Trie
cpp
1 | struct Trie01 { |
并查集
普通并查集
cpp
1 | struct DSU { |
树状数组
简单版, 单点修改
cpp
1 |
|
结构体版,单点修改
cpp
1 | struct fenwick_tree { |
结构体版,区间修改
cpp
1 | struct fenwick_tree { |
删除一个点,在前面/后面插入一个点
若n个点,m次删除。建立大小为n+m的树状数组,然后维护pos[i]表示i当前插在树状数组的哪个位置上。如果在前面插入,就把原来的数的初始位置插入在m+i的位置上,然后用cur记录前面可插入的位置,往前面插入即可。
分块
cpp
1 | int bl; |
逆序对
归并排序:
cpp
1 | template<class It> |
树状数组:
cpp
1 | struct fenwick_tree { |
线段树
cpp
1 | struct SegTree { |
动态开点
cpp
1 | struct SegTree { |
扫描线
cpp
1 | struct SegTree { |
权值线段树
cpp
1 | ll sumv[maxn*4]; |
Splay
cpp
1 | typedef int T; |
Splay压行
cpp
1 | template<class data_t=int, class Comp=std::less<data_t>> |
文艺Splay
cpp
1 | template<class data_t=int,class meta_t=int, class lazy_t=meta_t, class Comp=std::less<data_t>> |
文艺指针Splay
cpp
1 | template<typename T, typename Lz> |
主席树
cpp
1 | struct Persistable_SegTree { |
红黑树PBDS
cpp
1 | /by shenben |
哈希表pbds
cpp
1 | gp_hash_table<int,bool> h; |
莫队
cpp
1 | struct Mo { |
图论
拓扑排序
cpp
1 | struct Topo { // index from 1 |
二分图染色
cpp
1 | vector<int> G[maxn]; |
搜简单环
cpp
1 | vector<int> ring; |
SPFA,Bellman求负环
cpp
1 | vector<int> negCycle(int n) { |
Dijkstra
cpp
1 | struct Dijkstra { |
k短路
cpp
1 | vector<pair<int,ll>> G[maxn]; |
势能Dijkstra
cpp
1 | struct Dijkstra { |
Floyd
cpp
1 | // init: d[i][j] = len(i, j); d[i][i] = 0; else = INF |
Johnson全源最短路
cpp
1 | struct Johnson { |
最小生成树
cpp
1 | struct DSU { |
Tarjan 缩点,割点,桥
cpp
1 | struct Tarjan { |
2染色
cpp
1 | vector<int> col[3]; |
基环树
无向图基环树
cpp
1 | struct RingTree { |
最大团
cpp
1 | // n = |V| d = adj matrix |
树
LCA
cpp
1 | struct LCA { |
LCA(only node)
cpp
1 | struct LCA { |
树剖LCA
cpp
1 | int dep[maxn], fa[maxn], num[maxn], top[maxn], ind[maxn], son[maxn], way[maxn], lfa[maxn]; |
直径,重心
cpp
1 | struct Diameter { |
求点到直径的距离
把直径求出来,然后从直径bfs
换根dp
cpp
1 | typedef int T; |
点分治
cpp
1 |
|
DSU on Tree
cpp
1 | vector<int> G[maxn]; |
Path via LCA
cpp
1 | void dsut(int x, int fa, int kp) { |
字符串
KMP
cpp
1 | struct KMP { |
KMP Automaton
cpp
1 | struct KMP { |
Z function
cpp
1 | struct KMPZ { |
Trie
cpp
1 | struct Trie { |
Manacher
cpp
1 | struct Manacher { |
SAfast
cpp
1 | struct SuffixArray { |
SuffixArray
cpp
1 | struct SA { |
SuffixTree
cpp
1 | struct SuffixTree { |
广义后缀自动机
cpp
1 | struct SAM { |
网络流/二分图
匈牙利算法
cpp
1 | struct Match { |
二分图最大权完美匹配
cpp
1 | struct KM { |
Dinic(from Erik)
cpp
1 | struct Dinic { |
最小费用流
cpp
1 | typedef long long ll; |
Python
输入
python
1 | calc = 1 |
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.