Pagini recente » Cod sursa (job #2332094) | Cod sursa (job #2681003) | Cod sursa (job #593881) | Cod sursa (job #2128136) | Cod sursa (job #1243098)
#include <fstream>
#include <algorithm>
#include <vector>
#include <cmath>
#define DIM 100009
#define LG 20
#define pb push_back
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int n , m , Euler[ DIM * 2 ] , niv[ DIM * 2 ] , First[ DIM ] , K;
int dp[ 2 * DIM][ LG * 2];
vector < int > G[DIM];
typedef vector < int >:: iterator IT;
void Read();
void Dfs( int start , int lev );
void Rmq();
void Lca();
int main()
{
Read();
Dfs(1,0);
n = 2 * n - 1;
Rmq();
Lca();
return 0;
}
void Read()
{
in >> n >> m ;
for( int i = 2; i <=n ; i++)
{
int x;
in >> x;
G[x].pb(i);
}
}
void Dfs( int nod , int level )
{
Euler[++K] = nod;
niv[ K ] = level;
First[ nod] = K;
for( IT i = G[nod].begin() ; i!=G[nod].end() ; ++i)
{
Dfs(*i,level + 1 );
Euler[++K] = nod;
niv[K] = level;
}
}
void Rmq()
{
for( int i = 1 ;i <=n ; i++)
dp[i][0] = i;
int k = 0;
while( ( 1 << k ) <=n )
++k;
--k;
for( int j = 1 ; j <=k ; j++)
{
for( int i = 1; i<=n ; i++)
{
dp[i][j] = dp[i][j-1];
if( ( i + ( 1 << ( j - 1 ) ) <=n ) && niv[ dp[i][j] ] > niv[ dp[ i + ( 1 << ( j - 1 ) ) ][j-1]] )
dp[i][j] = dp[ i + ( 1 << ( j -1 ) )][ j - 1 ];
}
}
}
void Lca()
{
for( ; m ; --m)
{
int X , Y;
int x , y;
in >> X >> Y;
x = First[X];
y = First[Y];
if( x > y )
swap(x,y);
if( x == y )
{
out << Euler[dp[x][0]] << '\n';
continue;
}
int k = 0;
k = (int) floor( log( y - x )/log(2));
if( niv[dp[x][k]] <= niv[dp[ y - ( 1 << k ) + 1][k]] )
out << Euler[dp[x][k]] << '\n';
else
out << Euler[dp[ y - ( 1 << k ) + 1 ][k]] << '\n';
}
}