Pagini recente » Cod sursa (job #2843588) | Cod sursa (job #427757) | Cod sursa (job #1729126) | Cod sursa (job #3248189) | Cod sursa (job #1189881)
#include <fstream>
#include <vector>
using namespace std;
#define forit(it,v) for (auto it = v.begin() ; it != v.end() ; it++)
const int N = 1 + 1e5, LGLG = 5;
int head[LGLG][N], n;
int start[N], stop[N], timp;
vector<int> tree[N];
void mark(int x, int H){
head[0][x] = H;
forit(it, tree[x])
if ( !head[0][*it] )
mark(*it, H);
}
int dfs(int x){
start[x] = ++timp;
int weight = 1, best = -1, val, son;
forit(it, tree[x]){
val = dfs(*it);
weight += val;
if (best < val){
best = val;
son = *it;
}
}
forit(it, tree[x])
if (*it != son)
mark(*it, x);
stop[x] = ++timp;
return weight;
}
inline int isAncestor(int T, int x){
return start[T] <= start[x] && stop[x] <= stop[T];
}
int dumbLCA(int x, int y){
if ( isAncestor(x, y) )
return x;
for (int i = LGLG - 1 ; i >= 0 ; i--)
if ( !isAncestor(head[i][x], y) )
x = head[i][x];
return head[0][x];
}
int lca(int x, int y){
int X = dumbLCA(x, y), Y = dumbLCA(y, x);
return isAncestor(Y, X) ? X : Y;
}
void compute(){
dfs(1);
mark(1, 1);
for (int i = 1 ; i < LGLG ; i++)
for (int j = 1 ; j <= n ; j++)
head[i][j] = head[i - 1][ head[i - 1][j] ];
}
int main(){
int nrQ, x, y;
ifstream in("lca.in");
in >> n >> nrQ;
for (int i = 2 ; i <= n ; i++){
in >> x;
tree[x].push_back(i);
}
compute();
ofstream out("lca.out");
while (nrQ--){
in >> x >> y;
out << lca(x, y) << '\n';
}
in.close();
out.close();
return 0;
}