Pagini recente » Cod sursa (job #1252679) | Monitorul de evaluare | Monitorul de evaluare | Cod sursa (job #1329224) | Cod sursa (job #1488508)
#include <fstream>
#include <iostream>
#include <cmath>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
typedef struct nod{
int key;
nod *next;
} *lnod;
lnod A[100010];
int Euler[200010][18],N,M,Stack[100010],eul,st,Nivel[100010],niv,Index[100010];
void add(lnod &a,int key){
lnod b = new nod;
b->key = key;
b->next = a;
a = b;
}
void rez(int v){
int w;
while(A[v] != NULL){
Stack[++st] = v;
Euler[++eul][0] = v;
if(Index[v] == 0) Index[v] = eul;
Nivel[v] = niv++;
w = A[v]->key;
A[v] = A[v]->next;
v = w;
}
Euler[++eul][0] = v;
if(!Index[v]) Index[v] = eul;
Nivel[v] = niv--;
}
void euler(){
int v = 1;
do{
rez(v);
v = Stack[st--];
}while(st >= 0);
}
int log2s(int n){
return trunc(log2(n));
}
void RMQ_init(){
for(int k = 1; k <= log2s(eul);k++){
for(int i = 1; i +(1 << k) <= eul;i++){
if(Nivel[Euler[i][k-1]] < Nivel[Euler[i + (1 << (k-1))][k-1]])
Euler[i][k] = Euler[i][k-1];
else
Euler[i][k] = Euler[i + (1 << (k-1))][k-1];
}
}
}
int querry(int l, int r){
int dif = log2s(r - l + 1);
if(Nivel[Euler[l][dif]] < Nivel[Euler[r - (1 << dif)+1][dif]])
return Euler[l][dif];
else
return Euler[r - (1 << dif) + 1][dif];
}
int main(){
int x,y;
fin >> N >> M;
for(int i = 2;i<=N;i++){
fin >> x;
add(A[x],i);
}
euler();
RMQ_init();
for(int i = 0;i<M;i++){
fin >> x >> y;
if(Index[x] > Index[y])
fout << querry(Index[y],Index[x]);
else
fout << querry(Index[x],Index[y]);
fout << '\n';
}
return 0;
}