Pagini recente » Cod sursa (job #44419) | Cod sursa (job #786465) | Cod sursa (job #2123704) | Cod sursa (job #1635936) | Cod sursa (job #2134149)
#include <bits/stdc++.h>
#define dim 100005*2
std::ifstream in("lca.in");
std::ofstream out("lca.out");
using namespace std;
int nivel[ dim ], euler [ dim ] , rmq[ 25 ][ dim ] , first[dim] , lg[dim] ;
// nivel inseamna nivelul fiecarui nod
// euler e parcurgerea DFSSSS EULER
// rmq ul e matricea aia smechera
// first e prima aparitie a unui nod
int m ;
vector < int > G[100005]; // asta e grafu;
int n ,q ;
void Input()
{
in >> n >> q;
for(int i = 2;i <= n;i++)
{ int x;
in >> x;
G[x].push_back(i);
}
}
void dfs(int x,int bloc)
{
nivel[++m] = bloc;
euler[m] = x;
if(not first[x])
first[x] = m;
int l = G[x].size();
for(int i = 0;i < l;i++)
dfs(G[x][i] , bloc + 1) , nivel[++m] = bloc, euler[m] = x;
}
void rmqq()
{
lg[1] = 0 ;
for ( int i =2 ; i <= m ;++i)
lg [i] = lg[i / 2 ] + 1 ;
for ( int i =1 ; i <= m ; ++i)
rmq[0][i]=i;
for(int i =1 ; i <= lg[m] ; ++i)
for (int j = 1 ; j <= m- ( 1 <<(i-1) ) ; ++j)
{
if(nivel[rmq[i-1][j]]>nivel[rmq[i-1][j+(1<<(i-1))]])
rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
else
rmq[i][j]=rmq[i-1][j];
}
}
int lca ( int x, int y)
{
int a = first[x]; int b= first[y];
if(a>b)swap(a,b);
int k = lg[b-a+1];
int sol = min ( rmq[k][a] , rmq[k] [ b- (1<<(k))+1] );
return euler[sol];
}
int main()
{
Input();
dfs(1,0);
rmqq();
// for ( int i =1; i <=m ;++i)
// cout << euler[i] << " " << nivel [i ] << endl;
while(q--)
{
int x, y;
in >> x >> y;
out << lca(x, y) << "\n";
}
return 0;
}