Pagini recente » Cod sursa (job #869901) | Cod sursa (job #2177017) | Cod sursa (job #2575000) | Cod sursa (job #2530578) | Cod sursa (job #2601704)
#include <bits/stdc++.h>
#define N 100000
#define _log(x) 31-__builtin_clz(x)
using namespace std;
bitset <N+1> seen;
vector <int> G[N+1], euler, level;
int t[N+1], first[N+1], niv[N+1], seg[_log(N)+1][N];
void go (int x) {
euler.push_back(x);
level.push_back(niv[x]);
seen[x]=1;
for (auto it: G[x])
if (!seen[it]) {
first[it]=euler.size();
go(it);
}
euler.push_back(t[x]);
level.push_back(niv[t[x]]);
}
void rmq () {
int i, j, n=euler.size();;
for (i=0; i<n; ++i)
seg[0][i]=i;
for (i=1; (1<<i)<n; i++)
for (j=0; j+(1<<i)<=n; j++) {
int can1=seg[i-1][j],
can2=seg[i-1][j+(1<<i-1)];
if (level[can1]<level[can2])
seg[i][j]=can1;
else
seg[i][j]=can2;
}
}
int main () {
ifstream fin("lca.in");
ofstream fout("lca.out");
ios::sync_with_stdio(false);
int m, i, q, x, y;
fin >> n >> q;
for (i=2; i<=n; i++) {
fin >> x;
t[i]=x;
niv[i]=niv[x]+1;
G[x].push_back(i);
}
first[1]=euler.size();
go(1);
rmq();
for (; q; q--) {
fin >> x >> y;
x=first[x];
y=first[y];
if (x>y) i=x, x=y, y=i;
int lg=_log(y-x+1),
can1=seg[lg][x],
can2=seg[lg][y-(1<<lg)+1];
if (level[can1]<level[can2])
fout << euler[can1];
else
fout << euler[can2];
fout << '\n';
}
return 0;
}