Pagini recente » Cod sursa (job #1441268) | Cod sursa (job #2954888) | Cod sursa (job #2687093) | Cod sursa (job #515640) | Cod sursa (job #1985499)
#include <bits/stdc++.h>
using namespace std;
#define NMAX 100005
#define k_NMAX 17
ifstream f("lca.in");
ofstream g("lca.out");
int N, M, rmq[k_NMAX + 1][2 * NMAX], _first[NMAX];
int lg[2 * NMAX], euler[2 * NMAX], level[NMAX], eulerSize;
vector < int > G[NMAX];
void readInput() {
f >> N >> M;
for (int i = 2; i <= N; ++i) {
int x;
f >> x;
G[x].push_back(i);
}
}
void dfs(int node, int currentLevel) {
level[node] = currentLevel;
euler[++eulerSize] = node;
_first[node] = eulerSize;
for (auto it : G[node]) {
dfs(it, currentLevel + 1);
euler[++eulerSize]=node;
}
}
void computeRmq() {
rmq[0][1] = euler[1];
for (int i =2 ; i <= eulerSize; ++i) {
lg[i] = lg[i / 2] + 1;
rmq[0][i] = euler[i];
}
for (int i = 1; (1 << i) <= eulerSize; ++i)
for (int j = 1; j <= eulerSize - (1 << i) + 1; ++j) {
int x = rmq[i - 1][j];
int y = rmq[i - 1][j + (1 << (i - 1))];
if (level[x] < level[y]) rmq[i][j] = x;
else rmq[i][j] = y;
}
}
int lca(int node1, int node2) {
int st =_first[node1];
int dr =_first[node2];
if (st > dr)
swap(st, dr);
int k = lg[dr-st+1];
int x = rmq[k][st];
int y = rmq[k][dr - (1 << k) + 1];
if (level[x] < level[y])
return x;
return y;
}
void computeQueries() {
for (int i = 1; i <= M; ++i) {
int x, y;
f >> x >> y;
g << lca(x, y)<<'\n';
}
}
int main() {
readInput();
dfs(1, 0);
computeRmq();
computeQueries();
return 0;
}