Pagini recente » Cod sursa (job #2945146) | Cod sursa (job #431051) | Cod sursa (job #239639) | Cod sursa (job #3136856) | Cod sursa (job #1585488)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int N=100001;
vector<int>H[N];
int apar[100*N],lev[100*N],nr[100*N],dp[25][100*N],lg[100*N];
int k;
void dfs(int x,int lvl)
{
lev[++k]=lvl;//lev=>nivelul de pe pozitia k in repr euler;
nr[k]=x;//nr=>nodul de pe pozitia k in reprz euler;
apar[x]=k;//apar=>prima aparitie a nodului X in reprz euler;
for(vector<int>::iterator it=H[x].begin();it!=H[x].end();it++)
{
dfs(*it,lvl+1);
nr[++k]=x;
lev[k]=lvl;
}
}
void rmq()
{
int i,j;
lg[1]=0;
for(i=2;i<=k;i++) lg[i]=lg[i>>1]+1;
for(i=1;i<=k;i++) dp[0][i]=i;
for(i=1;(1<<i)<=k;i++)
{
for(j=1;j<=k-(1<<i)+1;j++)
{
dp[i][j]=dp[i-1][j];
if(lev[dp[i-1][j]]>=lev[dp[i-1][j+(1<<(i-1))]]) dp[i][j]=dp[i-1][j+(1<<(i-1))];
};
}
}
int mini(int a,int b)
{
if(a<=b) return a;
return b;
}
int minim(int a,int b)
{
a=apar[a];
b=apar[b];
if(a>b) swap(a,b);
int diff=lg[b-a];
return mini(dp[diff][a],dp[diff][b-(1<<diff)+1]);
}
int main()
{
int n,m,i,a,b;
fin>>n>>m;
for(i=2;i<=n;i++)
{
fin>>a;
H[a].push_back(i);
}
dfs(1,0);
rmq();
for(i=1;i<=m;i++)
{
fin>>a>>b;
fout<<nr[minim(a,b)]<<"\n";
}
}