Pagini recente » Cod sursa (job #1383427) | Cod sursa (job #92547) | Cod sursa (job #2058795) | Cod sursa (job #1942828) | Cod sursa (job #1369089)
#include <cstdio>
#include <algorithm>
#include <vector>
#define Nmax 200105
#define DIM 3666013
#define adancime first
#define nod second
using namespace std;
char buffer[DIM];
int Poz = DIM - 1;
void Scanf(int &A){
A = 0;
while('0' > buffer[Poz] || buffer[Poz] > '9')
if(++Poz == DIM)
fread(buffer,1,DIM,stdin),Poz = 0;
while('0' <= buffer[Poz] && buffer[Poz] <= '9'){
A = A * 10 + buffer[Poz] - 48;
if(++Poz == DIM)
fread(buffer,1,DIM,stdin),Poz = 0;
}
}
vector<vector<int> > G;
vector<int> poz;
pair<int,int> DP[18][Nmax];
int N,Q,pzc;
void Read(){
Scanf(N);Scanf(Q);
G.resize(N+1);
poz.resize(N+1);
int a;
for(int i = 2; i <= N; ++i){
Scanf(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(a);Scanf(b);
printf("%d\n",Query(a,b));
}
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
Read();
Solve();
return 0;
}