什么是长链剖分?
长链剖分是树链剖分的一种,与重链剖分不同,它选择子树深度最大的儿子作为长儿子,这样做的目的是优化处理与树深度相关的问题,比如查询k级祖先等。
长链剖分的主要性质
1、每个节点属于且仅属于一条长链;2、所有长链的节点和为N;3、k级祖先所在的长链长度必须大于等于k。
长链剖分的实现
定义数组来存储深度、长儿子、链顶等信息;第一次DFS(dfs1)负责计算深度、链长和长儿子;第二次DFS(dfs2)确定链顶。例如,使用dep数组记录深度,hson数组记录长儿子,top数组记录链顶。
C++长链剖分模板程序
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
vector<int> G[N];
int dep[N], len[N];
int fa[N], hson[N];
int top[N];
void dfs1(int u, int father) {
dep[u] = dep[father] + 1;
fa[u] = father;
hson[u] = 0;
len[u] = 1;
for(int v : G[u]) {
if(v == father) continue;
dfs1(v, u);
if(len[v] + 1 > len[u]) {
len[u] = len[v] + 1;
hson[u] = v;
}
}
}
void dfs2(int u, int tp) {
top[u] = tp;
if(hson[u]) {
dfs2(hson[u], tp);
for(int v : G[u]) {
if(v == fa[u] || v == hson[u]) continue;
dfs2(v, v);
}
}
}
int main() {
int root = 1;
dfs1(root, 0);
dfs2(root, root);
return 0;
}