Pagini recente » Istoria paginii runda/agora2004/clasament | Istoria paginii runda/oni_gim_2016/clasament | Cod sursa (job #1216297) | Cod sursa (job #1716011) | Cod sursa (job #2048599)
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
vector <int> G[100001];
vector <int> v, lev;
int first[100001];
int rmq[200002][32];
int lg2[200002];
void dfs(int nod = 1, int nivel = 1) {
v.push_back(nod);
lev.push_back(nivel);
first[nod] = v.size() - 1;
for(int i = 0; i < G[nod].size(); ++ i) {
dfs(G[nod][i], nivel + 1);
v.push_back(nod);
lev.push_back(nivel);
}
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int n, t;
scanf("%d%d", &n, &t);
for(int i = 2; i <= n; ++ i) {
int x;
scanf("%d", &x);
G[x].push_back(i);
}
dfs();
int m = lev.size();
for(int i = 0; i < m; ++ i) {
rmq[i][0] = i;
}
for(int i = 1; i < 32; ++ i) {
for(int j = 0; j + (1 << i) - 1 < m; ++ j) {
rmq[j][i] = rmq[j][i - 1];
if(lev[rmq[j][i]] > lev[rmq[j + (1 << (i - 1))][i - 1]]) {
rmq[j][i] = rmq[j + (1 << (i - 1))][i - 1];
}
}
}
for(int i = 2; i <= m; ++ i) {
lg2[i] = lg2[i / 2] + 1;
}
for(int i = 1; i <= t; ++ i) {
int x, y, l, r;
scanf("%d%d", &x, &y);
x = first[x];
y = first[y];
if(x > y) {
swap(x, y);
}
l = lg2[y - x + 1];
r = rmq[x][l];
if(lev[r] > lev[rmq[y - (1 << l) + 1][l]]) {
r = rmq[y - (1 << l) + 1][l];
}
printf("%d\n", v[r]);
}
return 0;
}