Pagini recente » Cod sursa (job #1417067) | Cod sursa (job #1819085) | Cod sursa (job #2817288) | Cod sursa (job #854765) | Cod sursa (job #1790955)
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> G;
int N, M;
const int Nmax = 205005;
int logDoi[Nmax];
int depth[18][Nmax];
int node[18][Nmax];
int nre;
void eulerDecompose(int k, int lvl)
{
++nre;
node[0][nre] = k;
depth[0][nre] = lvl;
for(auto it : G[k])
{
eulerDecompose(it, lvl + 1);
++nre;
node[0][nre] = k;
depth[0][nre] = lvl;
}
}
void buildRMQ()
{
int len = logDoi[nre];
int IT = 1;
for(int j = 1; j <= len; ++j) {
for(int i = 1; i <= nre; ++i)
if(i + IT <= nre) {
if(depth[j - 1][i] < depth[j - 1][i + IT]) {
depth[j][i] = depth[j - 1][i];
node[j][i] = node[j - 1][i];
}
else {
depth[j][i] = depth[j - 1][i + IT];
node[j][i] = node[j - 1][i + IT];
}
}
else {
depth[j][i] = depth[j][i-1];
node[j][i] = node[j][i-1];
}
IT <<= 1;
}
}
int poz[201005];
int queryRMQ(int a, int b)
{
if(a > b)
swap(a,b);
int lg = min(17, logDoi[b-a+1]);
if(depth[lg][a] <= depth[lg][b - (1<<lg) + 1])
return node[lg][a];
return node[lg][b - (1<<lg) + 1];
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
cin.sync_with_stdio(false);
cin >> N >> M;
G.resize(N + 1);
for(int i = 2; i < Nmax; ++i)
logDoi[i] = logDoi[i / 2] + 1;
for(int i = 2; i <= N; ++i) {
int x;
cin >> x;
G[x].push_back(i);
}
eulerDecompose(1, 0);
buildRMQ();
for(int i = 1; i <= nre; ++i)
if(!poz[node[0][i]])
poz[node[0][i]] = i;
for(int i = 1; i <= M; ++i) {
int x,y;
cin >> x >> y;
cout << queryRMQ(poz[x], poz[y]) << "\n";
}
return 0;
}