Pagini recente » Cod sursa (job #268370) | Cod sursa (job #645097) | Cod sursa (job #264366) | Cod sursa (job #2096159) | Cod sursa (job #1368921)
#include <cstdio>
#include <algorithm>
#include <vector>
#define Nmax 200105
#define adancime first
#define nod second
using namespace std;
vector<vector<int> > G;
vector<int> poz;
pair<int,int> DP[18][Nmax];
int N,Q,pzc;
void Read(){
scanf("%d%d",&N,&Q);
G.resize(N+1);
poz.resize(N+1);
int a;
for(int i = 2; i <= N; ++i){
scanf("%d",&a);
G[a].push_back(i);
}
}
void DFS(int k,int depth){
DP[0][++pzc] = make_pair(depth,k);
for(vector<int>::iterator it = G[k].begin(); it != G[k].end(); ++it)
{
DFS(*it,depth+1);
DP[0][++pzc] = make_pair(depth,k);
}
}
void RMQ()
{
int limi = 0,IT = 1;
while( (1<<(limi+1)) < pzc )
++limi;
for(int i = 1; i <= limi; ++i)
{
for(int j = 1; j <= pzc; ++j)
if(j + IT > pzc)
DP[i][j] = DP[i-1][j];
else
DP[i][j] = min(DP[i-1][j],DP[i-1][j+IT]);
IT *= 2;
}
}
int Query(int a,int b)
{
int x , y;
x = poz[a];
y = poz[b];
if(x > y)
swap(x,y);
int len = y - x + 1,IT = 1,lin = 0;
while( (IT<<1) <= len )
IT<<=1,++lin;
return min(DP[lin][x],DP[lin][y - IT + 1]).second;
}
void Solve()
{
DFS(1,0);
for(int i = 1; i <= pzc; ++i)
if(!poz[DP[0][i].nod])
poz[DP[0][i].nod] = i;
RMQ();
int a,b;
for(int i = 1; i <= Q; ++i){
scanf("%d%d",&a,&b);
printf("%d\n",Query(a,b));
}
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
Read();
Solve();
return 0;
}