Pagini recente » Cod sursa (job #1655331) | Cod sursa (job #1993390) | Cod sursa (job #687435) | Cod sursa (job #1131502) | Cod sursa (job #1134602)
#include <fstream>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
#define NMAX 100001
int i, j, N, M, T;
int X, Y;
int Ancestor[20][NMAX];
int Level[NMAX];
int Log[NMAX];
struct nod {
int U;
nod *next;
};
nod *v[NMAX];
bool used[NMAX];
void add(int A, int B) {
nod *P = new nod;
P->U = B;
P->next = v[A];
v[A] = P;
}
void DFS(int node) {
used[node] = true;
for (nod *it = v[node]; it; it = it->next) {
if (!used[it->U]) {
Level[it->U] = Level[node] + 1;
Ancestor[0][it->U] = node;
DFS(it->U);
}
}
}
void BringToLevel(int &X, int L) {
int cnt, n, k, last;
n = Level[X] - L;
last = X;
for (cnt = 1; cnt <= n; cnt <<= 1);
for (k = Level[X]; cnt; cnt >>= 1)
if (k - cnt >= L)
k -= cnt, last = Ancestor[Log[cnt]][last];
X = last;
}
int LCA(int X, int Y) {
int cnt = 0, k, lastX, lastY;
if (Level[Y] > Level[X]) swap(X, Y);
if (Level[X] != Level[Y])
BringToLevel(X, Level[Y]);
if (X == Y) return X;
lastX = X;
lastY = Y;
for (cnt = 1; cnt <= Level[X]; cnt <<= 1);
for (k = Level[X]; cnt; cnt >>= 1)
if (k - cnt >= 1 && Ancestor[Log[cnt]][lastX] != Ancestor[Log[cnt]][lastY])
k -= cnt, lastX = Ancestor[Log[cnt]][lastX], lastY = Ancestor[Log[cnt]][lastY];
return Ancestor[0][lastY];
}
int main() {
fin >> N >> M;
for (i = 2; i <= N; ++i) Log[i] = Log[(i >> 1)] + 1;
for (i = 2; i <= N; ++i) {
fin >> T;
add(i, T);
add(T, i);
}
DFS(1);
for (i = 1; (i << 1) <= N; ++i)
for (j = 2; j <= N; ++j)
Ancestor[i][j] = Ancestor[i - 1][ Ancestor[i - 1][j] ];
for (i = 1; i <= M; ++i) {
fin >> X >> Y;
fout << LCA(X, Y) << '\n';
}
return 0;
}