Pagini recente » Cod sursa (job #2249256) | Cod sursa (job #2951202) | Cod sursa (job #2874276) | Cod sursa (job #3196602) | Cod sursa (job #2633753)
#include <fstream>
#include <vector>
using namespace std;
ifstream in ("lca.in");
ofstream out ("lca.out");
void dfs ( int nod, int niv );
void famiUnEuler ();
void famiUnRMQ ();
void lca ( int a, int b );
int n, m;
int a, b;
int ind[100137];
int nivel[500137];
int lg2[500137];
int rmq[20][200137];
int euler[200137];
vector < int > v[100137];
int main()
{
in >> n >> m;
for ( register int i = 2 ; i <= n ; ++i )
{
in >> a;
v[a].push_back (i);
}
famiUnEuler ();
/*for ( register int i = 1 ; i <= euler[0] ; ++i )
out << euler[i] << " ";
out << '\n';
for ( register int i = 1 ; i <= euler[0] ; ++i )
out << nivel[i] << " ";
out << '\n';*/
famiUnRMQ ();
for ( register int i = 1 ; i <= m ; ++i )
{
in >> a >> b;
lca ( a, b );
}
return 0;
}
void famiUnEuler ()
{
dfs ( 1, 1 );
}
void dfs ( int nod, int niv )
{
euler[++euler[0]] = nod;;
nivel[euler[0]] = niv;
ind[nod] = euler[0];
for ( auto i : v[nod] )
{
dfs ( i, niv + 1 );
euler[++euler[0]] = nod;
nivel[euler[0]] = niv;
}
}
void famiUnRMQ ()
{
int k = euler[0];
for ( register int i = 2 ; i <= k ; ++i )
lg2[i] = lg2[i / 2] + 1;
for ( register int i = 1 ; i <= k ; ++i )
rmq[0][i] = i;
for ( register int i = 1 ; i <= lg2[k] ; ++i )
{
int put = ( 1 << i );
for ( register int j = 1 ; j <= k - put / 2 ; ++j )
if ( nivel[rmq[i - 1][j]] < nivel[rmq[i - 1][j + put / 2]] )
rmq[i][j] = rmq[i - 1][j];
else
rmq[i][j] = rmq[i - 1][j + put / 2];
}
}
void lca ( int a, int b )
{
a = ind[a];
b = ind[b];
if ( a > b )
swap ( a, b );
int lg = lg2[b - a + 1];
if ( nivel[rmq[lg][a]] < nivel[rmq[lg][b - ( 1 << lg ) + 1]] )
out << euler[rmq[lg][a]] << '\n';
else
out << euler[rmq[lg][b - ( 1 << lg ) + 1]] << '\n';
}