自用板子合集
1.自用板子合集
最近开始学新算法了;
篛嵇死了,啥也不会,只能背板子了;
快读
int型
inline int read() { int xr = 0,flag = 1; char lcr; while(lcr = getchar(),lcr < '0' or lcr > '9'){ if(lcr == '-'){ flag = -1; } } while(lcr >= '0' and lcr <= '9'){ xr = (xr << 3) + (xr << 1) + (lcr ^ 48); lcr = getchar(); } return xr * flag; }
快写
void write(int x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); return; }
二叉树相关
1、深度优先DFS:
前序遍历(根,左子树,右子树)
void dfs(int x){ printf("%d\n",x); if(ls[x]) dfs(ls[x]); if(rs[x]) dfs(rs[x]); }
中序遍历(左子树,根,右子树)
void dfs(int x){ if(ls[x]) dfs(ls[x]); printf("%d\n",x); if(rs[x]) dfs(rs[x]); }
后续遍历(左子树,右子树,根)
void dfs(int x){ if(ls[x]) dfs(ls[x]); if(rs[x]) dfs(rs[x]); printf("%d\n",x); }
2、广度优先BFS:
层次遍历(从上到下,从左到右依次输出同一层的节点):
void bfs(int x){ q[++top] = x; for(int i = 1; i <= top; i ++){ int now = q[i]; printf("%d\n",now); if(ls[now]) q[++top] = ls[now]; if(rs[now]) q[++top] = rs[now]; } }
动规
1、01背包(已降维)
for(int i = 1; i <= n; i ++){ for(int j = m; i >= w[i]; j --){ dp[j] = max(dp[j],dp[j - w[i]] + v[i]); } }
2、完全背包
for(int i = 1; i <= n; i ++){ for(int j = w[i]; i <= m; j ++){ dp[j] = max(dp[j],dp[j - w[i]] + v[i]); } }
3、背包计数
(若要求恰好为m,则dp[0]初始化为1,其他均为0);
for(int i = 1; i <= n; i ++){ for(int j = m; i >= w[i]; j --){ dp[j] += dp[j - w[i]]; } }
4、二进制拆分(用于多重背包)
for(int i = 1; i <= n1; i ++){ scanf("%d %d %d",&a, &b, &c); for(int k = 1; k <= c; k <<= 1){ v[++u] = k * a; w[u] = k * b; c -= k; } if(c) v[++u] = a * c,w[u] = b * c; }
并查集
1、查询 + 路径压缩
int find(int x){ return fa[x] == x ? x : fa[x] = find(fa[x]); }
2、合并x,y所属集合
void marge(int x, int y){ int u = find(x), v = find(y); if(u == v) return; fa[u] = v; }
3、合并x, y 所属集合(按秩合并)
void marge(int x, int y){ int u = find(x), v = find(y); if(u == v) return; if(rk[u] > rk[v]) swap(u,v); // 把深度小的合并到深度大的上面; fa[u] = v; rk[v] += rk[u] == rk[v]; //如果同级,则合并后深度加一,否则不变; }
单调队列
//n为数据个数,m为窗口长度; for(int i = 1; i <= n; i ++){ if(q[head] <= i - m) head ++; while(head <= tail && a[q[tail]] < a[i]) tail --; q[++tail] = i; ans[i] = a[q[head]]; } for(int i = m ; i <= n ; i ++){ //对每个窗口中已选出的数据进行处理 ; }
图论
1、链式前向星
void add(int x, int y){ to[++cnt] = y; nxt[cnt] = head[x]; head[x] = cnt; }
2.spfa
void spfa() { memset(dis,0x3f,sizeof dis); dis[s] = 0; z[top = 1] = s; for(int j = 1;j <= top;++ j){ int now = z[j]; vis[now] = 0; for(int i = head[now];i;i = nxt[i]){ if(dis[to[i]] > dis[now] + w[i]){ dis[to[i]] = dis[now] + w[i]; if(!vis[to[i]]){ vis[to[i]] = 1; z[++ top] = to[i]; } } } } }
线段树
1.初始建树
inline void build(int l,int r,int id) { if(l == r){ sum[id] = a[l]; return; } int mid = (l + r) >> 1; build(l,mid,id * 2); build(mid + 1,r,id * 2 + 1); sum[id] = sum[id * 2] + sum[id * 2 + 1]; }
2.单点查询
inline int query(int l,int r,int id,int x) { if(l == r){ return sum[id]; } int mid = (l + r) >> 1; if(x <= mid){ query(l,mid,id * 2,x); } else{ query(mid + 1,r,id * 2 + 1,x); } }
3.单点修改
inline void change(int l,int r,int x,int v,int k) { if(l == r){ sum[k] += v; return; } int mid = (l + r) >> 1; int res = 0; if(x <= mid){ change(l,mid,x,v,k * 2); } else{ change(mid + 1,r,x,v,k * 2 + 1); } sum[k] = sum[k * 2] + sum[k * 2 + 1]; }
4.区间查询
nt query(int l,int r,int x,int y,int k)//区间[x,y] { if(x <= l and y >= r){ return sum[k]; } int mid = (l + r) >> 1; int res = 0; if(x <= mid){ res += query(l,mid,x,y,k * 2); } if(y >= mid){ res += query(mid + 1,r,x,y,k * 2 + 1); } return res; }
5.带懒标记的区间修改查询
//lazytag inline void add_(int l,int r,int k,int v) { add[k] += v; sum[k] += v * (r - l + 1); } inline void pushdown(int l,int r,int mid,int k) { if(!add[k]){ return; } add_(l,mid,add[k],k * 2); add_(mid + 1,r,add[k],k * 2 + 1); add[k] = 0; } inline int query(int l,int r,int x,int y,int k) { if(x <= l and y >= r){ return sum[k]; } int mid = (l + r) >> 1; int res = 0; pushdown(l,r,mid,k); if(x <= mid){ res += query(l,mid,x,y,k * 2); } if(y > mid){ res += query(mid + 1,r,x,y,k * 2 + 1); } return res; } void change(int l,int r,int x,int y,int k,int v) { if(x <= l and y >= r){ return sum[k]; } int mid = (r + l) >> 1; int res = 0; pushdown(l,r,mid,k); if(x <= mid){ change(l,mid,x,y,k * 2,v); } if(y > mid){ change(mid + 1,r,x,y,k * 2 + 1,v); } sum[k] = sum[k * 2] + sum[k * 2 + 1]; }
字符串
1.kmp
//n为a的长度,m为b的长度 inline void jiannxt() { nxt[1] = 0; for(int i = 1,j = 0;i < m;++ i){ while(j and b[j + 1] != b[i + 1]){ j = nxt[j]; } if(b[j + 1] == b[i + 1]){ ++ j; } nxt[i + 1] = j; } } inline int kmp() { int ans = 0; for(int i = 0;i < n;++ i){ while(j and b[j + 1] != a[i + 1]){ j = nxt[j]; } if(b[j + 1] == a[i + 1]){ ++ j; } if(j == m){ ++ ans; j = nxt[j]; } } return ans; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具