Pagini recente » Cod sursa (job #1465241) | Cod sursa (job #600139) | Cod sursa (job #1503778) | Cod sursa (job #2967970) | Cod sursa (job #1324097)
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
#define NMAX 100010
#define NMAX_Log 30
#define NMAX_Euler 200010
#define Enode(x) Euler[x].first
#define Edepth(x) Euler[x].second
int N;
int FirstInEuler[NMAX];
int ST[NMAX][NMAX_Log];
vector < int > G[NMAX];
vector < pair < int , int > > Euler;
void ConstructEulerPath(int n, int lvl)
{
Euler.push_back(make_pair(n,lvl));
FirstInEuler[n] = Euler.size() - 1;
for(vector < int > :: iterator it = G[n].begin(); it!=G[n].end(); it++)
{
ConstructEulerPath(*it,lvl+1);
Euler.push_back(make_pair(n,lvl));
}
}
void ConstructSpareTable()
{
for(int i=1;i<Euler.size();i++)
ST[i][0] = i;
for(int j=1; (1<<j) <Euler.size(); j++)
for(int i=1;i + (1<<j) <= Euler.size();i++)
{
int minOnFirstSegment,minOnSecondSegment;
minOnFirstSegment = ST[i][j-1];
minOnSecondSegment = ST[i + (1<<(j-1))][j-1];
if(Edepth(minOnFirstSegment) <= Edepth(minOnSecondSegment))
ST[i][j] = minOnFirstSegment;
else
ST[i][j] = minOnSecondSegment;
}
}
int LCA(int i , int j)
{
int a,b;
a = FirstInEuler[i];
b = FirstInEuler[j];
if(a>b)
swap(a,b);
int lg = (int) log2(double(b - a + 1));
int minOnFirstSegment,minOnSecondSegment;
minOnFirstSegment = ST[a][lg];
minOnSecondSegment = ST[b - (1<<lg) + 1][lg];
if(Edepth(minOnFirstSegment) <= Edepth(minOnSecondSegment))
return Enode(minOnFirstSegment);
return Enode(minOnSecondSegment);
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
int M,x,y;
scanf("%d%d",&N,&M);
for(int i=2;i<=N;i++)
{
scanf("%d",&x);
G[x].push_back(i);
}
Euler.push_back(make_pair(0,0));
ConstructEulerPath(1,0);
ConstructSpareTable();
while(M--)
{
scanf("%d%d",&x,&y);
printf("%d\n",LCA(x,y));
}
return 0;
}