Pagini recente » Cod sursa (job #2543413) | Cod sursa (job #413679) | Cod sursa (job #438773) | Cod sursa (job #980103) | Cod sursa (job #1500690)
#include <cstdio>
#include <cmath>
using namespace std;
const int Nmax = (int) 1e5;
const int NIL = -1;
struct List {
int v, next;
};
List l[Nmax];
int adj[Nmax];
int father[Nmax], d[Nmax], gr[Nmax];
int sqrtN;
void inline addEdge(int u, int v, int pos) {
l[pos].v = v;
l[pos].next = adj[u];
adj[u] = pos;
}
void DFS(int u, int depth, int group) {
d[u] = depth;
gr[u] = group;
if (depth % sqrtN == 0) {
group = u;
}
for (int i = adj[u]; i != NIL; i = l[i].next) {
int v = l[i].v;
if (father[v] == NIL) {
father[v] = u;
DFS(v, depth + 1, group);
}
}
}
int inline lca(int u, int v) {
while (gr[u] != gr[v]) {
if (d[u] > d[v]) {
u = gr[u];
} else {
v = gr[v];
}
}
while (u != v) {
if (d[u] > d[v]) {
u = father[u];
} else {
v = father[v];
}
}
return u;
}
int main(void) {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int n, m;
int u, v;
scanf("%d%d", &n, &m);
memset(adj, NIL, sizeof(adj));
memset(father, NIL, sizeof(father));
for (int i = 1; i < n; i++) {
scanf("%d", &u);
addEdge(u - 1, i, i);
}
sqrtN = (int) sqrt(n - 1) + 1;
DFS(0, 1, 0);
for (int i = 0; i < m; i++) {
scanf("%d%d", &u, &v);
printf("%d\n", lca(u - 1, v - 1) + 1);
}
fclose(stdin);
fclose(stdout);
return 0;
}