Pagini recente » Cod sursa (job #2644373) | Cod sursa (job #3202248) | Cod sursa (job #2519603) | Cod sursa (job #965042) | Cod sursa (job #2560652)
#include <bits/stdc++.h>
#define pb push_back
#define st first
#define nd second
using namespace std;
ifstream fin ( "lca.in" );
ofstream fout ( "lca.out" );
int rmq[400005][50], n, m;
int lg[400005];
int niv[400005];
int first[100005];
vector<int>g[100005];
vector<int>euler;
void build_rmq() {
int k = euler.size();
k--;
for ( int i = 2; i <= k; i++ )
lg[i] = lg[i / 2] + 1;
for ( int i = 0; i <= k; i++ )
rmq[i][0] = i;
for ( int j = 1; j <= lg[k]; j++ )
for ( int i = 0; i + ( 1 << ( j - 1 ) ) <= k; i++ ) {
rmq[i][j] = rmq[i][j - 1];
if ( niv[rmq[i][j]] > niv[rmq[i + ( 1 << ( j - 1 ) )][j - 1]] )
rmq[i][j] = rmq[i + ( 1 << ( j - 1 ) )][j - 1];
}
}
int query ( int l, int r ) {
int x, y;
x = l, y = r;
l = min ( first[x], first[y] );
r = max ( first[x], first[y] );
int d = r - l + 1;
int k = lg[d];
int sol = rmq[l][k];
if ( niv[sol] > niv[rmq[r - ( 1 << k ) + 1][k]] )
sol = rmq[r - ( 1 << k ) + 1][k];
return euler[sol];
}
void dfs ( int x, int l ) {
euler.pb ( x );
niv[euler.size() - 1] = l;
first[x] = euler.size() - 1;
for ( auto it : g[x] ) {
dfs ( it, l + 1 );
euler.pb ( x );
niv[euler.size() - 1] = l;
}
}
int main() {
fin >> n >> m;
for ( int i = 1; i < n; i++ ) {
int x;
fin >> x;
g[x].pb ( i + 1 );
}
dfs ( 1, 0 );
build_rmq();
while ( m-- ) {
int x, y;
fin >> x >> y;
fout << query ( x, y ) << '\n';
}
return 0;
}