Pagini recente » Cod sursa (job #2385712) | Cod sursa (job #2128174) | Cod sursa (job #2432921) | Cod sursa (job #984436) | Cod sursa (job #1452424)
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int Nmax = 100010;
const int LgMax = 19;
int n , m , i , dad , node1 , node2;
int ap[Nmax] , Log[Nmax<<1];
pair < int , int > D[LgMax][Nmax<<1];
vector < int > g[Nmax];
vector < pair < int , int > > euler;
void dfs(int node , int level)
{
euler.push_back({node , level});
for (int i = 0; i < g[node].size(); ++i)
{
dfs(g[node][i] , level + 1);
euler.push_back({node , level});
}
}
void rmq()
{
int i , j , n = euler.size();
for (i = 1; i <= n; ++i)
{
D[0][i] = euler[i-1];
if (!ap[euler[i-1].first])
ap[euler[i-1].first] = i;
}
for (Log[1] = 0, i = 2; i <= n; ++i)
Log[i] = Log[i>>1] + 1;
for (i = 1; i <= Log[n]; ++i)
for (j = 1; j <= n - (1 << i) + 1; ++j)
{
if (D[i-1][j].second < D[i-1][j+(1<<(i-1))].second)
D[i][j] = D[i-1][j];
else D[i][j] = D[i-1][j+(1<<(i-1))];
}
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
scanf("%d %d", &n, &m);
for (i = 2; i <= n; ++i)
{
scanf("%d", &dad);
g[dad].push_back(i);
}
dfs(1 , 0); rmq();
for (i = 1; i <= m; ++i)
{
scanf("%d %d", &node1, &node2);
int left = ap[node1]; int right = ap[node2]; if (left > right) swap(left , right);
int ind = Log[right-left+1];
if (D[ind][left].second < D[ind][right-(1<<ind)+1].second)
printf("%d\n", D[ind][left].first);
else printf("%d\n", D[ind][right-(1<<ind)+1].first);
}
return 0;
}