Pagini recente » Cod sursa (job #1331134) | Istoria paginii runda/winners2 | Cod sursa (job #1233146) | Cod sursa (job #2565697) | Cod sursa (job #1936195)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int NMax = 1e5 + 5;
int N,M,H,root;
int dad[NMax],level[NMax],an[NMax];
vector<int> v[NMax];
void dfs(int,int);
void build(int,int);
int query(int,int);
int main() {
in>>N>>M;
for (int i=2;i<=N;++i) {
in>>dad[i];
v[dad[i]].push_back(i);
}
dfs(1,1);
for (root=1;root*root <= H;++root) ;
--root;
build(1,1);
/*
for (int i=1;i<=N;++i) {
out<<dad[i]<<' ';
}
out<<'\n';
//*/
while (M--) {
int x,y;
in>>x>>y;
if (level[x] < level[y]) {
swap(x,y);
}
out<<query(x,y)<<'\n';
}
return 0;
}
void dfs(int x,int d) {
if (H < d) {
H = d;
}
level[x] = d;
for (int k=0;k<v[x].size();++k) {
dfs(v[x][k],d+1);
}
}
void build(int x,int d) {
if (d % root == 1) {
an[x] = dad[x];
}
else {
an[x] = an[dad[x]];
}
for (int k=0;k<v[x].size();++k) {
build(v[x][k],d+1);
}
}
int query(int x,int y) {
while (an[x] != an[y]) {
if (level[x] > level[y]) {
x = an[x];
}
else {
y = an[y];
}
}
while (x != y) {
if (level[x] > level[y]) {
x = dad[x];
}
else {
y = dad[y];
}
}
return x;
}