Pagini recente » Cod sursa (job #2642581) | Cod sursa (job #806991) | Cod sursa (job #1184689) | Cod sursa (job #1140123) | Cod sursa (job #1144560)
#include <cstdio>
#include <vector>
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstring>
#define Nmax 100005
#define INF 0x3f3f3f3f
using namespace std;
int N,M,NR;
int AP[2*Nmax];
vector<int> G[Nmax];
pair<int,int> range[19][2*Nmax];
bitset<Nmax>used;
void read()
{
int x;
scanf("%d%d",&N,&M);
for(int i = 2; i <= N; ++i)
{
scanf("%d",&x);
G[x].push_back(i);
}
}
void LCA(int k ,int niv)
{
range[0][++NR] = make_pair(niv,k);
used[k] = 1;
for(vector<int>::iterator it = G[k].begin(); it != G[k].end();++it)
if(!used[*it])
{
LCA(*it,niv+1);
range[0][++NR] = make_pair(niv,k);
}
}
void Build()
{
for(int i = 1; i <= NR; ++i)
if(!AP[range[0][i].second])
AP[range[0][i].second] = i;
int len =(int)log2(NR),it = 1;
for(int k = 1; k <= len; ++k)
{
for(int i = 1; i <= NR; ++i)
if(range[k-1][i] < range[k-1][i+it])
range[k][i] = range[k-1][i];
else
range[k][i] = range[k-1][i+it];
it<<=1;
}
}
pair<int,int> Querry(int a,int b)
{
int len =(int)log2(b-a+1);
if(range[len][a].first < range[len][b-(1<<len)].second)
return range[len][a];
return range[len][b-(1<<len)];
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
read();
memset(range,INF,sizeof(range));
LCA(1,0);
Build();
int a,b;
for(int i = 1; i <= M; ++i)
{
scanf("%d%d",&a,&b);
if(AP[a]>AP[b]) swap(a,b);
printf("%d\n",Querry(AP[a],AP[b]).second);
}
return 0;
}