Pagini recente » Cod sursa (job #3265755) | Cod sursa (job #3030685) | Cod sursa (job #2540113) | Cod sursa (job #2835257) | Cod sursa (job #2399264)
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int nMax = 100000;
vector<int> g[nMax + 5];
int n, m, v[2 * nMax + 5];
int lca[nMax + 5], dim;
int lvl[nMax + 5];
int rmq[20][nMax * 2 + 5];
int lg[2 * nMax + 5];
void DFS(int nod, int lev) {
v[++dim] = nod;
lvl[dim] = lev;
lca[nod] = dim;
for (auto i : g[nod]) {
DFS(i, lev + 1);
v[++dim] = nod;
lvl[dim] = lev;
}
}
void RMQ() {
for (int i = 2; i <= dim; i++)
lg[i] = lg[i >> 1] + 1;
for (int i = 1; i <= dim; i++)
rmq[0][i] = i;
for (int i = 1; (1 << i) < dim; i++)
for (int j = 1; j <= dim - (1 << i); j++) {
int k = 1 << (i - 1);
rmq[i][j] = rmq[i - 1][j];
if (lvl[rmq[i - 1][j + k]] < lvl[rmq[i][j]])
rmq[i][j] = rmq[i - 1][j + k];
}
}
int LCA(int x, int y) {
int a = lca[x], b = lca[y];
if (a > b)
swap(a, b);
int dif = b - a + 1;
int p = lg[dif];
int st = rmq[p][a], dr = rmq[p][a + dif - (1 << p)];
if (lvl[st] > lvl[dr])
return v[dr];
return v[st];
}
int main() {
fin >> n >> m;
for (int i = 2; i <= n; i++) {
int x;
fin >> x;
g[x].push_back(i);
}
DFS(1, 0);
RMQ();
for (int i = 1; i <= m; i++) {
int x, y;
fin >> x >> y;
fout << LCA(x, y) << '\n';
}
}