-
Notifications
You must be signed in to change notification settings - Fork 153
/
Copy pathkth_ancestor_tree.cpp
71 lines (57 loc) · 1.36 KB
/
kth_ancestor_tree.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
* Description: Level Ancestor (Finds the Kth level ancestor of a node in tree using sparse table)
* Usage: assign, process O(N lg(N)), query O(lg(N))
* Note: The tree should in form of an array P where P[i] represents parent of i th node.
* Source: https://github.com/dragonslayerx
*/
class levelAncestor
{
private:
vector<size_t> tree;
vector<vector<size_t> > LA;
public:
levelAncestor(){}
levelAncestor(size_t size){
assign(size);
}
template<class value> levelAncestor(const vector<value> &T){
assign(T);
}
template<class value> void assign(const vector<value> &T){
clear();
tree.resize(T.size());
for(size_t i=0;i<tree.size();i++) tree[i]=T[i];
}
void process(){
size_t lgn=0;
for(size_t sz=tree.size();sz;sz>>=1,lgn++);
LA.resize(lgn,vector<size_t>(tree.size()));
for(size_t j=0;j<LA[0].size();j++)
LA[0][j]=tree[j];
for(size_t i=1;i<LA.size();i++)
for(size_t j=0;j<LA[i].size();j++)
LA[i][j]=LA[i-1][LA[i-1][j]];
}
size_t& operator [](size_t pos){
return tree[pos];
}
size_t query(size_t node,size_t level) const{
int k=0;
int current=node;
for(;level;level>>=1,k++) {
if(level&1) {
current=LA[k][current];
}
}
return current;
}
size_t size() const{
return tree.size();
}
void clear(){
tree.clear();
}
~levelAncestor(){
clear();
}
};