网站首页 > 技术文章 正文
1
倍增法(Doubling Method)
倍增法详细解题思路1. 概述倍增法(Binary Lifting)是一种在处理与树或图相关的问题时常用的算法技巧,特别是在计算最近公共祖先(LCA)、树上路径查询等问题中非常有用。倍增法的核心思想是通过预处理,使得在查询时能够快速地跳过多个节点,从而达到减少查询时间复杂度的目的。2. 预处理阶段2.1 深度和祖先计算
3. 查询阶段
3.1 调整深度
- 调整节点深度:将较深的节点调整到与另一个节点同一深度。通过从高位到低位的二进制位检查,逐步调整节点。
3.2 逼近最近公共祖先
- 逼近LCA:在同一深度基础上,通过倍增法逐步逼近最近公共祖先。同样从高位到低位检查,逐步调整节点。
4. 总结
倍增法通过预处理每个节点的深度和第 (2^k) 个祖先,使得在查询最近公共祖先时能够快速跳过多个节点,从而大大减少查询时间复杂度。这种方法在处理大规模树结构的查询问题时非常高效。
示例代码
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const int MAXN = 100005; // 最大节点数
const int LOG = 20; // 二进制位数
vector<int> adj[MAXN]; // 邻接表存储树
int parent[MAXN][LOG]; // 存储每个节点的第2^k个祖先
int depth[MAXN]; // 存储每个节点的深度
// 深度优先搜索,预处理深度和祖先
void dfs(int node, int par, int dep) {
depth[node] = dep;
parent[node][0] = par;
for (int i = 1; i < LOG; ++i) {
if (parent[node][i-1] != -1) {
parent[node][i] = parent[parent[node][i-1]][i-1];
}
}
for (int child : adj[node]) {
if (child != par) {
dfs(child, node, dep + 1);
}
}
}
// 计算最近公共祖先
int lca(int u, int v) {
if (depth[u] < depth[v]) swap(u, v);
// 将u调整到与v同一深度
for (int i = LOG - 1; i >= 0; --i) {
if (depth[u] - (1 << i) >= depth[v]) {
u = parent[u][i];
}
}
if (u == v) return u;
// 同时向上跳,逼近LCA
for (int i = LOG - 1; i >= 0; --i) {
if (parent[u][i] != parent[v][i]) {
u = parent[u][i];
v = parent[v][i];
}
}
return parent[u][0];
}
int main() {
int n, q;
cin >> n >> q;
// 读取树的边
for (int i = 1; i < n; ++i) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
// 初始化parent数组
for (int i = 0; i < MAXN; ++i) {
for (int j = 0; j < LOG; ++j) {
parent[i][j] = -1;
}
}
// 预处理深度和祖先
dfs(1, -1, 0);
// 处理查询
while (q--) {
int u, v;
cin >> u >> v;
cout << "LCA of " << u << " and " << v << " is " << lca(u, v) << endl;
}
return 0;
}
猜你喜欢
- 2024-10-26 CSP-J 2021 初赛单项选择真题及解析
- 2024-10-26 CSP-NOIP信息学竞赛 算法(02)由鸡兔同笼看限定条件
- 2024-10-26 掌握C++冒泡排序算法 |3D动画编程教育软件首发 #冒泡算法#CSP
- 2024-10-26 2022 CSP-S组 第一轮认证试题与答案解析!
- 2024-10-26 CSP-J/S常考算法探秘:不用比较也能排序(3)——桶排序
- 2024-10-26 CCF四川大学学生分会举办CSP认证和算法学习经验分享会
- 2024-10-26 CSP-J初赛知识点 十大排序算法 结构体和联合体区别
- 2024-10-26 自创一道差分和快排分区算法的题(CSP-J2难度)
- 2024-10-26 CSP高分说 | 武汉大学徐嘉浩:热爱不止于此——我的算法之旅
- 2024-10-26 CSP-S 复赛知识点梳理 csp复赛获奖比例
你 发表评论:
欢迎- 最近发表
-
- 在 Spring Boot 项目中使用 activiti
- 开箱即用-activiti流程引擎(active 流程引擎)
- 在springBoot项目中整合使用activiti
- activiti中的网关是干什么的?(activiti包含网关)
- SpringBoot集成工作流Activiti(完整源码和配套文档)
- Activiti工作流介绍及使用(activiti工作流会签)
- SpringBoot集成工作流Activiti(实际项目演示)
- activiti工作流引擎(activiti工作流引擎怎么用)
- 工作流Activiti初体验及在数据库中生成的表
- Activiti工作流浅析(activiti6.0工作流引擎深度解析)
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)