Pagini recente » Cod sursa (job #324781) | Cod sursa (job #1270292) | Cod sursa (job #2734904) | Cod sursa (job #3038677) | Cod sursa (job #1231563)
#include <fstream>
#include <algorithm>
#include <vector>
#define NN 100005
#define INF 0x3f3f3f3f
#define pb push_back
using namespace std;
ofstream out("lca.out");
ifstream in("lca.in");
int n , m ;
int K;
int Lev[ NN * 2 ] , Eul[ NN * 2] , First[ NN ] ;
int arb[ NN << 4];
int lsol , sol , st , dr;
vector < int > G[NN];
typedef vector< int >::iterator IT;
void Read();
void Dfs( int start , int level );
void build( int nod , int li , int lf );
void query( int nod , int li , int lf );
int lca( int x , int y );
int main()
{
Read();
Dfs(1,0);
build(1,1,K);
for( ; m ; --m )
{
int x , y;
in >> x >> y;
out << lca( x , y ) << '\n';
}
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 )
{
Eul[ ++K ] = nod;
Lev[ K ] = level;
First[ nod ] = K;
for( IT i = G[nod].begin(); i!=G[nod].end(); ++i)
{
Dfs( *i , level + 1 );
Eul[ ++K ] = nod;
Lev[ K ] = level;
}
}
void build( int nod , int li , int lf )
{
if( li == lf )
{
arb[nod] = li;
return;
}
int mid = ( li + lf ) >> 1;
build( ( nod << 1 ) , li , mid );
build( ( nod << 1 ) + 1 , mid + 1 ,lf );
if( Lev[arb[ (nod<<1) ]] <= Lev[arb[ (nod<<1)+1]] )
arb[nod] = arb[(nod<<1)];
else
arb[nod] = arb[(nod<<1)+1];
}
void query( int nod , int li , int lf )
{
if( st <=li && lf <= dr)
{
if( Lev[arb[nod]] < lsol )
sol = Eul[arb[nod]] , lsol = Lev[arb[nod]];
return;
}
int mid = ( li + lf ) >> 1;
if( st <= mid )
query( ( nod << 1 ) , li , mid );
if( mid < dr )
query( ( nod << 1 ) + 1 , mid + 1 , lf );
}
int lca( int x , int y )
{
st = First[x];
dr = First[y];
if( st > dr )
swap(st,dr);
sol = lsol = INF;
query(1,1,K);
return sol;
}