当前位置: 首页 > news >正文

20251027 - 倍增 ST表

前言:

怎么标题改来改去的?

概念

因为每一个整数都可以转换成对应的二进制,所以可以表示成 \(a_0 \times 2^0 + a_1 \times 2 ^ 1 + a_2 \times 2 ^ 2 + a_{len} \times 2 ^ {len}\)

因此,对于求跳 \(x\) 步后的状态,可以先预处理 \(2^{len}\) 的表,每次跳跃从一步一步往上跳进化成每次跳 \(2^{i}\) 步。

这就是倍增的概念。

用处

比如求 \(\operatorname{LCA}\),就可以用倍增从 \(O(qn)\) 优化到 \(O(q \log _2n)\)

接下来的 ST 表也是运用了倍增!

ST 表

ST 表(Sparse Table),是处理静态 RMQ 问题的一种高效算法(可重复贡献问题)。

对于无法进行相加减得到区间答案的问题,如 \(\max,\min\),并且区间重叠对答案不受影响的(加或减就不是),可使用 ST 表来求解 RMQ。

\(dp_{i,j}\) 为以 \(i\) 为起点,往右 \(2^j\) 个单位的极值是多少。

那么就可以用 \(dp_{i,j-1}\)\(dp_{i+(1<<j-1),j-1}\) 求极值。

单词询问时,就像扣了两锅盖,把两个锅盖求极值就好了!

优点:单次询问是 \(O(1)\)

缺点:无法在低时间复杂度修改 ST 表

所以,能用 ST 表就不用线段树(常数之王)!

例题:最近公共祖先(LCA)

方法 ( \(T\) 次询问)

1. 暴力法

记录深度,把深度较深的节点向上移动

时间复杂度:\(O(Tn)\)

2. 倍增

预处理每个节点向上 \(2^k\) 层的祖先

查询时通过二进制跳跃快速找到 \(\operatorname{LCA}\)

dp[i][j] = dp[dp[i][j-1]][j-1];

时间复杂度:\(O(T\log_2n)\)

3.dfs 序

对树进行 \(dfs\) 遍历,记录访问顺序和深度

记录每个节点首次出现的位置

\(ST\) 表来求出两个节点 dfs 序之间深度最小的节点

时间复杂度:\(O(n \log _2n + T)\)

代码(倍增):

#include <bits/stdc++.h>using namespace std;
const int N = 5e5 + 7;
const int LOG_N = 21;
int f[N][LOG_N],dep[N];
vector<int>ve[N];
inline void dfs(int u,int fa){for(auto v : ve[u]){if(v == fa) continue;dep[v] = dep[u] + 1;f[v][0] = u;dfs(v,u);}return;
}
int get_lca(int x,int y){if(dep[x] < dep[y]) swap(x,y);int d = dep[x] - dep[y];for(int i = 0;d;i++,d >>= 1){if(d & 1){x = f[x][i];}}if(x != y){for(int i = 20;i >= 0;i--){if(f[x][i] != f[y][i]){x = f[x][i];y = f[y][i];}}x = f[x][0];	}return x;
}
int n,m,s;
int main(){scanf("%d%d%d",&n,&m,&s);for(int i = 1,x,y;i < n;i++){scanf("%d%d",&x,&y);ve[x].push_back(y);ve[y].push_back(x);}dep[s] = 1;dfs(s,s);for(int j = 1;j <= 20;j++){for(int i = 1;i <= n;i++){f[i][j] = f[f[i][j-1]][j-1];}}for(int u,v;m--;){scanf("%d%d",&u,&v);printf("%d\n",get_lca(u,v));}return 0;
}
http://www.jsqmd.com/news/24909/

相关文章:

  • 周康阳精选冲刺省选国赛思维训练题
  • Luogu P7913 [CSP-S 2021] 廊桥分配 题解 [ 绿 ] [ 贪心 ] [ 前缀和 ] [ STL ]
  • 10-27 CSP 赛前比赛记录
  • P3939 数颜色
  • 完整教程:Docker 搭建 Nginx 并启用 HTTPS 具体部署流程
  • AI开发微信小程序-有感
  • 价值流智能时代:DevOps平台如何成为企业高效交付的核心引擎? - 教程
  • 2025年压力容器品牌综合实力排行榜
  • 2025年压力容器厂家综合评测与选择指南
  • 2025年口碑好的压力容器工厂/厂家前十强
  • 科幻——面包
  • 2025年中国钢结构码垛机制造商Top 5排名解析
  • 2025年钢结构码垛机品牌前十强权威盘点:江苏众利达引领智能制造新浪潮
  • 处理django.db.utils.OperationalError: attempt to write a readonly database错误
  • 10.28代码大全2
  • [GESP202509 二级] 菱形
  • 11hhs
  • linux 配置vnc
  • 2025 ICPC 成都 游记
  • 基于PSO粒子群优化算法的64QAM星座图的最优概率整形matlab仿真,对比PSO优化前后整形星座图和误码率
  • 第七周第二天7.2
  • apisix流量高峰期服务卡住问题
  • 第七周第一天7.1
  • 第六周第五天6.5
  • 在vue-markdown-render中解析LaTeX公式
  • 完整教程:IP 地址管理:IPv4 和 IPv6 地址规划、子网划分与 CIDR
  • 102302107_林诗樾_数据采集与融合技术实践作业1
  • Day25-C:\Users\Lenovo\Desktop\note\code\JavaSE\Basic\src\com\Threadcase-多线程讲到等待唤醒机制的一半
  • C++primer 类的静态成员
  • CSP-S NOIP 2025 备考