Pagini recente » Cod sursa (job #2437121) | Cod sursa (job #1495044) | Cod sursa (job #2717258) | Cod sursa (job #956301) | Cod sursa (job #2968026)
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 100100;
const int LGMAX = 19;
int N, M, Q;
int positionNode[NMAX], pow_2[NMAX], dad[NMAX], depth[NMAX];
vector<pair <int, int>> euler;
pair <int, int> lca[LGMAX][NMAX];
vector <int> edges[NMAX];
void read(){
scanf("%d%d", &N, &Q);
int x;
for(int i = 2; i <= N; i++){
scanf("%d", &x);
dad[i] = x;
edges[i].push_back(x);
edges[x].push_back(i);
}
}
void dfs(int node, int dad){
euler.push_back(make_pair(depth[node], node));
positionNode[node] = euler.size() - 1;
for(auto it : edges[node]){
if(it == dad)
continue;
depth[it] = depth[node] + 1;
dfs(it, node);
euler.push_back(make_pair(depth[node], node));
}
}
void buildRMQ(){
M = euler.size() - 1;
for(int i = 1; i <= M; i++)
lca[0][i] = euler[i];
for(int k = 1; k < LGMAX; k++)
for(int i = 1; i <= M; i++){
lca[k][i] = lca[k - 1][i];
if(lca[k][i].first > lca[k - 1][i + (1 << (k - 1))].first)
lca[k][i] = lca[k - 1][i + (1 << (k - 1))];
}
for(int i = 2; i < NMAX; i++)
pow_2[i] = pow_2[i / 2] + 1;
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
read();
euler.push_back(make_pair(0, 0));
dfs(1, 0);
buildRMQ();
int x, y, length;
pair <int, int> ans;
while(Q--){
scanf("%d%d", &x, &y);
x = positionNode[x];
y = positionNode[y];
if(x > y)
swap(x, y);
length = pow_2[y - x];
ans = lca[length][x];
if(ans.first > lca[length][y - (1 << length) + 1].first)
ans = lca[length][y - (1 << length) + 1];
printf("%d\n", ans.second);
}
return 0;
}