Pagini recente » Cod sursa (job #50215) | Cod sursa (job #1421357) | Borderou de evaluare (job #1058045) | Cod sursa (job #114288) | Cod sursa (job #1427611)
#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[2 * MaxN], E[2 * MaxN], firstAppearance[MaxN], k, rmq[MaxN][4 * MaxLG];
int lg[2 * 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];
if (a > b) {
int temp = a;
a = b;
b = temp;
}
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;
}