Pagini recente » Cod sursa (job #1304614) | Statistici Goidescu Rares-Stefan (raresgoidescu) | Cod sursa (job #2571823) | Cod sursa (job #1232708) | Cod sursa (job #1225730)
#include <cstdio>
#include <vector>
#include <cmath>
#define Nmax 100105
#define DIM 2666013
#define next (++pointer == DIM) ? fread(buffer,1,DIM,stdin),pointer = 0 : 0
char buffer[DIM];
int pointer = DIM - 1;
void scanf(int &A){
A = 0;
for(;'0'>buffer[pointer]||buffer[pointer]>'9';next);
for(;'0'<=buffer[pointer]&&buffer[pointer]<='9';next)
A = A * 10 + buffer[pointer] - 48;
}
using namespace std;
vector<int> G[Nmax];
int N,M;
int euler[18][2*Nmax];
int adanc[18][2*Nmax];
int poz[Nmax],nre;
void read()
{
scanf(N),scanf(M);
int a;
for(int i = 2; i <= N; ++i)
{
scanf(a);
G[a].push_back(i);
}
}
void DFS(int k,int niv)
{
euler[0][++nre] = k;
adanc[0][nre] = niv;
for(vector<int>::iterator it = G[k].begin(); it != G[k].end(); ++it)
{
DFS(*it,niv+1);
euler[0][++nre] = k;
adanc[0][nre] = niv;
}
}
void rmq()
{
int leng = (int)log2(nre),IT = 1;
for(int j = 1; j <= leng; ++j)
{
for(int i = 1; i <= nre; ++i)
if(i + IT <= nre)
{
if(adanc[j-1][i] < adanc[j-1][i+IT])
{
adanc[j][i] = adanc[j-1][i];
euler[j][i] = euler[j-1][i];
}
else
{
adanc[j][i] = adanc[j-1][i+IT];
euler[j][i] = euler[j-1][i+IT];
}
}
else
{
euler[j][i] = euler[j][i-1];
adanc[j][i] = adanc[j][i-1];
}
IT *= 2;
}
}
void prepare()
{
DFS(1,0);
rmq();
}
int Querry(int a,int b)
{
if(a > b) swap(a,b);
int lg = min((int)log2(b-a+1),17);
if(adanc[lg][a] <= adanc[lg][b - (1<<lg) + 1] )
return euler[lg][a];
return euler[lg][b - (1<<lg) + 1];
}
void solve()
{
int a,b;
for(int i = 1; i <= nre; ++i)
if(!poz[euler[0][i]])
poz[euler[0][i]] = i;
for(int i = 1; i <= M; ++i)
{
scanf(a),scanf(b);
printf("%d\n",Querry(poz[a],poz[b]));
}
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
read();
prepare();
solve();
return 0;
}