Pagini recente » Cod sursa (job #1299805) | Cod sursa (job #1468486) | Cod sursa (job #3183250) | Cod sursa (job #527568) | Cod sursa (job #1393821)
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;
const int Nmax = 100011 ;
const int LgNx = 20 ;
const int Mmax = 2000011 ;
int N,M,L;
vector< int > V[Nmax];
int Rmq[LgNx][Nmax << 2];
int Lg[Nmax << 1];
int High[Nmax << 1];
int Lvl[Nmax << 1];
int First[Nmax];
ifstream F("lca.in");
ofstream G("lca.out");
void Get( int Nod , int Niv)
{
High[ ++L ]=Nod;
Lvl[ L ]=Niv;
First[ Nod ]=L;
for (int i=0;i<int( V[Nod].size() );++i)
{
Get( V[Nod][i] , Niv+1 );
High[ ++L ]=Nod;
Lvl[ L ]=Niv;
}
}
void Build()
{
for (int i=1;i<=L;++i)
Lg[i]=Lg[i>>1]+1;
for (int i=1;i<=L;++i)
Rmq[0][i]=i;
for (int i = 1; (1 << i) < L; ++i)
for (int j = 1; j <= L - (1 << i); ++j)
{
int l = 1 << (i - 1);
Rmq[i][j] = Rmq[i-1][j];
if ( Lvl[Rmq[i-1][j + l]] < Lvl[Rmq[i][j]] )
Rmq[i][j] = Rmq[i-1][j + l];
}
}
int LCA(int x, int y)
{
int Difrence, l, Sol, Sift;
int a = First[x];
int b = First[y];
if (a > b) swap(a, b);
Difrence = b - a + 1;
l = Lg[ Difrence ]-1;
Sol = Rmq[l][a];
Sift = Difrence - (1 << l);
if( Lvl[Sol] > Lvl[Rmq[l][a + Sift]] )
Sol = Rmq[l][a + Sift];
return High[Sol];
}
int main()
{
F>>N>>M;
for (int i=2;i<=N;++i)
{
int x;
F>>x;
V[x].push_back( i );
}
Get( 1,0 );
Build();
while ( M-- )
{
int x,y;
F>>x>>y;
G<<LCA( x,y )<<'\n';
}
}