Kth Ancestor 第k个祖先问题

题目出处

这道题目出自hackerrank的8月月赛的第三题。

题目大意

先给出一棵树

之后有三种操作分别为:加边,查询,和删除一个节点

查询的时候要给出任意节点x的第k个祖先

每组数据有t个case

每个case边(P)的数量小于等于10^5

每个case的操作的数量(Q)小于等于10^5

题目分析

一开始拿到这个题目的时候被搞得一头雾水,如果采用普通的暴力的办法,每一个查询需要O(P),总体的复杂度就变成了O(Q*P),铁定TLE…

思考了三天没有什么想法然后搜了一下,发现了这个:

Level ancestor problem

研读了一番之后发现了使用一个神奇的数据结构,使得每一次的查询可以降为long(P)的复杂度,这样问题就迎刃而解了。

这个奇特的数据结构,我这样描述:

对树进行DFS,记录下每一条路径e[i]。

之后开一个node[i]标记每个节点所在的边号(index),以及在该边的深度(depth)还有该点的“父节点”(father 该点所在边的起点e[node[i].index][0]的父节点)。

那么查询的时候Q(x,k)就等于:

k <= node[x].depth 时 return e[node[x].index][node[x].depth-k]

k > node[x].depth 时 return Q(node[x].father,k-1)

之后就是一系列的边界描述,不再赘述了。

第一次写出来的这个代码十分之丑陋,大家见笑了

python3写的

Level ancestor


以后争取做到学会了就记录下来,这个代码贴给后人鄙视吧

原文地址:https://www.cnblogs.com/qoshi/p/3327929.html