Pagini recente » Cod sursa (job #2129001) | Cod sursa (job #77475) | Cod sursa (job #620997) | Cod sursa (job #2348538) | Cod sursa (job #3001696)
#include <fstream>
#include <vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
vector < int > v[100005];
int n, m , h[1000005] , euler[1000005] , first[100005] , k , arbore[1000005] , minim , nr;
const int inf = 1e9;
void dfs(int nod , int nivel)
{
euler[++k] = nod;
h[k] = nivel;
first[nod] = k;
for ( int i = 0 ; i < v[nod] . size() ; i++)
{
dfs(v[nod][i] , nivel + 1);
euler[++k] = nod;
h[k] = nivel;
}
}
void buildtree(int nod , int left , int right)
{
if(left == right)
{
arbore[nod] = left;
return ;
}
int mid = (left + right) / 2;
buildtree( 2 * nod , left , mid);
buildtree( 2 * nod + 1 , mid + 1 , right);
if(h[arbore[2 * nod]] <= h[arbore[2 * nod + 1]])
arbore[nod] = arbore[2 * nod];
else
arbore[nod] = arbore[2 * nod + 1];
}
void querry(int nod , int left , int right , int qleft , int qright)
{
if( left >= qleft && right <= qright)
{
if(h[arbore[nod]] <= minim)
{
minim = h[arbore[nod]];
nr = euler[arbore[nod]];
}
return ;
}
int mid = (left + right) / 2;
if(qleft <= mid)
querry(2 * nod , left , mid , qleft , qright);
if(qright > mid)
querry(2 * nod + 1 , mid + 1 , right , qleft , qright);
}
int lca(int x , int y)
{
int st = first[x];
int dr = first[y];
if(st > dr)
swap(st , dr);
minim = inf;
nr = 0;
querry( 1 , 1 , k , st , dr);
return nr;
}
int main()
{
f >> n >> m;
for (int i = 2 ; i <= n ; i++)
{
int x = 0;
f >> x;
v[x] . push_back(i);
}
dfs(1 , 0);
buildtree(1 , 1 , k);
for ( int i = 1 ; i <= m ; i++)
{
int x , y;
f >> x >> y;
g << lca(x , y) << '\n';
}
}