数据结构板子
st表#
int query(int l, int r) { int k = __lg(r - l + 1); return __gcd(st[l][k], st[r - (1 << k) + 1][k]); } void solve() { // 此处维护区间gcd for(int i = 1; i <= n; i++) { st[i][0] = abs(a[i + 1] - a[i]); } for(int k = 1; k <= __lg(n); k++) { for(int i = 1; i + (1 << k) - 1 <= n; i++) { st[i][k] = __gcd(st[i][k - 1], st[i + (1 << k - 1)][k - 1]); } } }
树状数组#
// 此题开了21个树状数组,非常恶心 int tr[22][K + 10]; int lowbit(int x) { return x & -x; } void update(int i, int x, int d) { x++; while(x <= K) { tr[i][x] += d; x += lowbit(x); } } int qu(int i, int x) { x++; int ans = 0; while(x) { ans += tr[i][x]; x -= lowbit(x); } return ans; } int query(int i, int l, int r) { return qu(i, r) - qu(i, l - 1); }
动态开点线段树#
void update(int i, ll l, ll r, ll q, int x) { num[i] = x; if(l == r) return; ll mid = (l + r) / 2; if(q <= mid) { if(!ls[i]) ls[i] = ++cnt; update(ls[i], l, mid, q, x); } else { if(!rs[i]) rs[i] = ++cnt; update(rs[i], mid + 1, r, q, x); } }
树链剖分#
ll w0[N]; int dep[N], f[N], sz[N], son[N]; void dfs1(int l, int i) { f[i] = l; dep[i] = dep[l] + 1; int ms = -1; for(int j = 0; j < v[i].size(); j++) { int t = v[i][j]; if(t == l) continue; dfs1(i, t); sz[i] += sz[t] + 1; if(sz[t] > ms) { ms = sz[t]; son[i] = t; } } } int id[N], z, up[N]; ll w[N]; void dfs2(int i, int iup) { z++; id[i] = z; w[z] = w0[i]; up[i] = iup; if(son[i] == 0) return; dfs2(son[i], iup); for(int j = 0; j < v[i].size(); j++) { int t = v[i][j]; if(t == f[i] || t == son[i]) continue; dfs2(t, t); } } ll sum[N * 4], lz[N * 4]; void pushup(int i) { sum[i] = sum[i * 2] + sum[i * 2 + 1]; sum[i] %= mo; } void build(int i, int l, int r) { if(l == r) { sum[i] = w[l]; return; } int mid = (l + r) / 2; build(i * 2, l, mid); build(i * 2 + 1, mid + 1, r); pushup(i); } void pushdown(int i, int l, int r) { if(lz[i]) { int mid = (l + r) / 2; sum[i * 2] += (mid - l + 1) * lz[i]; sum[i * 2] %= mo; sum[i * 2 + 1] += (r - mid) * lz[i]; sum[i * 2 + 1] %= mo; lz[i * 2] += lz[i]; lz[i * 2] %= mo; lz[i * 2 + 1] += lz[i]; lz[i * 2 + 1] %= mo; lz[i] = 0; } } void modify(int i, int l, int r, int ql, int qr, ll d) { if(ql <= l && qr >= r) { sum[i] += (r - l + 1) * d; sum[i] %= mo; lz[i] += d; lz[i] %= mo; return; } pushdown(i, l, r); int mid = (l + r) / 2; if(ql <= mid) modify(i * 2, l, mid, ql, qr, d); if(qr > mid) modify(i * 2 + 1, mid + 1, r, ql, qr, d); pushup(i); } ll query(int i, int l, int r, int ql, int qr) { if(ql <= l && qr >= r) return sum[i]; pushdown(i, l, r); int mid = (l + r) / 2; ll ans = 0; if(ql <= mid) ans += query(i * 2, l, mid, ql, qr); if(qr > mid) ans += query(i * 2 + 1, mid + 1, r, ql, qr); ans %= mo; pushup(i); return ans; } void op1(int x, int y, ll d) { while(up[x] != up[y]) { if(dep[up[x]] < dep[up[y]]) swap(x, y); modify(1, 1, n, id[up[x]], id[x], d); x = f[up[x]]; } if(dep[x] > dep[y]) swap(x, y); modify(1, 1, n, id[x], id[y], d); } ll op2(int x, int y) { ll ans = 0; while(up[x] != up[y]) { if(dep[up[x]] < dep[up[y]]) swap(x, y); ans += query(1, 1, n, id[up[x]], id[x]); ans %= mo; x = f[up[x]]; } if(dep[x] > dep[y]) swap(x, y); ans += query(1, 1, n, id[x], id[y]); ans %= mo; return ans; }
作者:Aderose_yr
出处:https://www.cnblogs.com/meowqwq/p/18401591
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
喵喵喵)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】