Pagini recente » Istoria paginii runda/dpg1/clasament | Cod sursa (job #2562767) | Cod sursa (job #1627396) | Cod sursa (job #156068) | Cod sursa (job #2376372)
#include <bits/stdc++.h>
#define NMAX 100005
using namespace std;
ifstream fin( "lca.in" );
ofstream fout( "lca.out" );
int N;
int nrq;
vector <int> Ad[NMAX];
int M;
int euler[2*NMAX];
int level[NMAX];
int poz[NMAX];
int rmq[30][2*NMAX];
int lg[2*NMAX];
void DFS( int nod, int lvl )
{
int i, w;
euler[++M] = nod;
if ( poz[nod] == 0 )
{
level[nod] = lvl;
poz[nod] = M;
}
for ( i = 0; i < Ad[nod].size(); ++i )
{
w = Ad[nod][i];
DFS( w, lvl + 1 );
euler[++M] = nod;
}
}
void gen_euler()
{
DFS( 1, 1 );
}
void RMQ()
{
int i, j, a, b;
for ( i = 1; i <= M; ++i )
rmq[0][i] = euler[i];
for ( i = 2; i <= M; ++i )
lg[i] = lg[i/2] + 1;
for ( i = 1; ( 1 << i ) <= M; ++i )
for ( j = 1; j + ( 1 << i ) + 1 <= M; ++j )
{
a = rmq[ i - 1 ][ j ];
b = rmq[ i - 1 ][ j + ( 1 << ( i - 1 ) ) ];
if ( level[a] < level[b] )
rmq[i][j] = a;
else rmq[i][j] = b;
}
}
int LCA( int x, int y )
{
int a, b;
int k, sol;
a = poz[x];
b = poz[y];
if ( a > b ) swap( a, b );
k = lg[b-a+1];
sol = rmq[k][a];
if ( level[ rmq[k][a] ] > level[ rmq[k][ b - ( 1 << k ) + 1 ] ] )
sol = rmq[k][ b - ( 1 << k ) + 1 ];
return sol;
}
void read()
{
int i, x, y;
fin >> N >> nrq;
for ( i = 2; i <= N; ++i )
{
fin >> x;
Ad[x].push_back( i );
}
gen_euler();
RMQ();
for ( i = 1; i <= nrq; ++i )
{
fin >> x >> y;
fout << LCA( x, y ) << '\n';
}
fin.close();
}
int main()
{
read();
fout.close();
return 0;
}