专栏文章

树上倍增

算法·理论参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miqkzjmy
此快照首次捕获于
2025/12/04 06:31
3 个月前
此快照最后确认于
2025/12/04 06:31
3 个月前
查看原文

树上倍增

豪用

求第Y个祖先

N个节点的树,M次询问第X个节点的第Y个祖先 n,m<=1e4n, m <= 1e4
f[x][2]=f[f[x][1]][1],f[x][y+y]=f[f[x][y]][y]f[x][2] = f[f[x][1]][1], f[x][y + y] = f[f[x][y]][y]
定义数组F[x][y] = f[x][2y 2 ^ y] 。
节点祖先的性质,易得F[x][y + 1] = F[F[x][y]][y]
从小到大枚举y,求出一切节点的F[x][y],如此往复,通过已知的F[x][y]求出F[x][y + 1]。
y 的上界:O(longnlong _ n),因此预处理O(n * lognlog_n)

模版

CPP
void init(){
	for(int i = 1 ; i <= n ; i ++)
		F[i][0] = fa[i];
	for(int i = 1 ; i <= 20; i ++)
		for(int j = 1 ; j <= n ; j ++){
			if(F[j][i - 1] > 0 && F[F[j][j - 1]][j - 1] > 0)
				F[j][i] = F[F[j][i - 1]][i - 1];
		}
}

int f(int x, int n){
	for(int i = 20; i >= 0;; i --){
		if(n >= (1 << i)){
			n -= (1 << i);
			x = F[x][i];
		}
	}
	return x;
}

求LCA

倍增求F[x][k],代表节点x的第 2k2^k 个祖先。

评论

0 条评论,欢迎与作者交流。

正在加载评论...