Pagini recente » Cod sursa (job #2480953) | Cod sursa (job #2525489) | Cod sursa (job #1319588) | Cod sursa (job #1428157) | Cod sursa (job #1103551)
#include <fstream>
#include <algorithm>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
#define L (n << 1)
#define R (L | 1)
#define NMAX 100001
struct nod {
int u;
nod *next;
};
nod *v[NMAX];
int H[3 * NMAX];
int level[NMAX];
int euler[NMAX];
int first[NMAX];
bool used[NMAX];
inline void add(int i, int j) {
nod *p = new nod;
p->u = j;
p->next = v[i];
v[i] = p;
}
inline int query(int n, int l, int r, int i, int j) {
if (i <= l && r <= j) return H[n];
int m = (l + r) >> 1;
int sol = 0;
if (i <= m) {
int cnt = query(L, l, m, i, j);
if (level[cnt] < level[sol])
sol = cnt;
}
if (j > m) {
int cnt = query(R, m + 1, r, i, j);
if (level[cnt] < level[sol])
sol = cnt;
}
return sol;
}
int K;
void DFS(int node) {
used[node] = true;
euler[++K] = node;
first[node] = K;
for (nod *it = v[node]; it; it = it->next) {
if (!used[it->u]) {
level[it->u] = level[node] + 1;
DFS(it->u);
euler[++K] = node;
}
}
}
void build(int n, int l, int r) {
if (l == r){H[n] = euler[l]; return;}
int m = (l + r) >> 1;
build(L, l, m);
build(R, m + 1, r);
if (level[H[L]] < level[H[R]]) H[n] = H[L];
else
H[n] = H[R];
}
int i, j, N, M, T;
int X, Y;
int main() {
fin >> N >> M;
for (i = 2; i <= N; ++i) {
fin >> T;
add(i, T);
add(T, i);
}
DFS(1);
build(1, 1, K);
level[0] = 0x3f3f3f3f;
for (i = 1; i <= M; ++i) {
fin >> X >> Y;
if (first[X] > first[Y]) swap(X, Y);
fout << query(1, 1, K, first[X], first[Y]) << '\n';
}
return 0;
}