Pagini recente » Cod sursa (job #355037) | Borderou de evaluare (job #1216312) | Cod sursa (job #644630) | Borderou de evaluare (job #2509068) | Cod sursa (job #3313591)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX = 100005;
const int LMAX = 2 * NMAX;
int n, m;
vector<int> G[NMAX];
int viz[NMAX];
int euler[LMAX];
int euler_nivel[LMAX];
int first[NMAX];
int cnt = 0;
int lg2_[LMAX];
int rmq[20][LMAX];
void dfs(int x, int nv) {
viz[x] = 1;
euler[++cnt] = x;
euler_nivel[cnt] = nv;
first[x] = cnt;
for (auto vecin : G[x]) {
dfs(vecin, nv + 1);
euler[++cnt] = x;
euler_nivel[cnt] = nv;
}
}
void build_rmq() {
for (int i = 2; i <= cnt; i++) lg2_[i] = lg2_[i / 2] + 1;
for (int i = 1; i <= cnt; i++) rmq[0][i] = i;
for (int k = 1; (1 << k) <= cnt; k++) {
for (int i = 1; i + (1 << k) - 1 <= cnt; i++) {
int a = rmq[k - 1][i];
int b = rmq[k - 1][i + (1 << (k - 1))];
rmq[k][i] = (euler_nivel[a] < euler_nivel[b] ? a : b);
}
}
}
int rmq_euler_nivel(int l, int r) {
if (l > r) swap(l, r);
int k = lg2_[r - l + 1];
int a = rmq[k][l];
int b = rmq[k][r - (1 << k) + 1];
return (euler_nivel[a] < euler_nivel[b] ? a : b);
}
int LCA(int x, int y) {
int indice = rmq_euler_nivel(first[x], first[y]);
return euler[indice];
}
int main() {
fin >> n >> m;
for (int i = 2; i <= n; i++) {
int p;
fin >> p;
G[p].push_back(i);
}
dfs(1, 0);
build_rmq();
while (m--) {
int u, v;
cin >> u >> v;
cout << LCA(u, v) << "\n";
}
return 0;
}