Pagini recente » Cod sursa (job #1329928) | Cod sursa (job #1072733) | Cod sursa (job #2445504) | Cod sursa (job #2681693) | Cod sursa (job #2134074)
#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 ; (1<<i)<m; ++i)
for ( int j =1 ; j<= m-(1<<i); ++j)
{
int l = 1 <<(i-1);
rmq[i][j]=rmq[i-1][j];
if(nivel[rmq[i-1][j+l]] < nivel[rmq[i][j]])
rmq[i][j]=rmq[i-1][j+l];
}
}
int lca ( int x, int y)
{
int diff,l,sol,sh;
int a = first[x] , b= first[y];
if (a>b)swap(a,b);
diff=b-a+1;
l=lg[diff];
sol=rmq[l][a];
sh=diff-(1<<l);
if(nivel[sol]>nivel[rmq[l][a+sh]])
sol=rmq[l][a+sh];
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;
}