Pagini recente » Cod sursa (job #2070320) | Cod sursa (job #207535) | Cod sursa (job #2888294) | Cod sursa (job #1942234) | Cod sursa (job #1427606)
#include <fstream>
#include <vector>
#define MaxN 100005
#define MaxLG 20
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int N, M, L[3 * MaxN], E[3 * MaxN], firstAppearance[MaxN], k, rmq[MaxN][MaxLG];
int lg[MaxN];
vector<int> G[MaxN];
int min(int a, int b) {
return a < b ? a : b;
}
void dfs(int node, int level) {
E[++k] = node;
L[k] = level;
firstAppearance[node] = k;
for (unsigned int i = 0; i < G[node].size(); ++i) {
dfs(G[node][i], level + 1);
E[++k] = node;
L[k] = level;
}
}
void build_rmq() {
for (int i = 2; i <= k; ++i)
lg[i] = lg[i / 2] + 1;
for (int i = 1; i <= k; ++i)
rmq[i][0] = i;
for (int j = 1; (1 << j) <= k; ++j) {
for (int i = 1; i + (1 << j) - 1 <= k; ++i) {
int half = 1 << (j - 1);
int minn = min(L[rmq[i][j - 1]], L[rmq[i + half][j - 1]]);
rmq[i][j] = minn == L[rmq[i][j - 1]] ? rmq[i][j - 1] : rmq[i + half][j - 1];
}
}
}
int lca(int x, int y) {
int a = firstAppearance[x];
int b = firstAppearance[y];
int diff = b - a + 1;
int lg2 = lg[diff];
int offset = diff - (1 << lg2);
if (L[rmq[a][lg2]] < L[rmq[a + offset][lg2]])
return E[rmq[a][lg2]];
else
return E[rmq[a + offset][lg2]];
}
int main() {
fin >> N >> M;
for (int i = 2; i <= N; ++i) {
int x;
fin >> x;
G[x].push_back(i);
}
dfs(1, 0);
build_rmq();
for (int i = 1; i <= M; ++i) {
int x, y;
fin >> x >> y;
fout << lca(x, y) << '\n';
}
return 0;
}