Pagini recente » Cod sursa (job #1022368) | Cod sursa (job #2083955) | Cod sursa (job #1033017) | Cod sursa (job #121095) | Cod sursa (job #2198234)
#include <bits/stdc++.h>
#define dimn 100005
#define diml 20
std::ifstream f("lca.in");
std::ofstream g("lca.out");
int N, Q;
std::vector <int> son[dimn];
int neuler, euler[dimn*2];
int level[dimn*2], first[dimn];
int lg[dimn*2], rmq[diml][dimn*4]; //pt rmq, lucram cu repr euler
void dfs(int nod=1, int nivel=0) {
euler[++neuler] = nod;
level[neuler] = nivel;
first[nod] = neuler;
for (int i=0; i<son[nod].size(); i++) {
dfs(son[nod][i], nivel+1);
euler[++neuler] = nod;
level[neuler] = nivel;
}
}
void calc_rmq() {
for (int i=2; i<=neuler; i++)
lg[i] = lg[i>>1] + 1;
for (int i=1; i<=neuler; i++)
rmq[0][i] = i;
for (int i=1, j, len; (1<<i) < neuler; i++)
for (j=1; j<=neuler - (1<<i); j++) {
len = 1<<(i - 1);
rmq[i][j] = rmq[i-1][j];
if(level[rmq[i-1][j+len]] < level[rmq[i][j]])
rmq[i][j] = rmq[i-1][j+len];
}
}
int min_interval(int a, int b) {
int diff = b - a + 1;
int len = lg[diff];
int index = rmq[len][a];
if(level[index] > level[rmq[len][a + diff - (1<<len)]])
index = rmq[len][a + diff - (1<<len)];
return index;
}
int lca(int x, int y) {
int a = first[x], b = first[y];
if(a>b) std::swap(a, b);
int sol = min_interval(a, b);
return euler[sol];
}
void citire() {
f >> N >> Q;
for (int i=1, x; i<N; i++) {
f >> x;
son[x].push_back(i+1);
}
}
void rezolvare() {
dfs();
calc_rmq();
int y, x;
while(Q--) {
f >> x >> y;
g << lca(x, y) << "\n";
}
}
int main()
{
citire();
rezolvare();
return 0;
}