Pagini recente » Cod sursa (job #2116414) | Cod sursa (job #977987) | Cod sursa (job #21404) | Cod sursa (job #3151368) | Cod sursa (job #2759527)
/*
Sursa experimentala
*/
#include <iostream>
#include <fstream>
#include <vector>
#define NMAX 100000 //o suta de mii
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
struct element{
int nod;
int height;
};
int dimE;
int first[NMAX + 1], last[NMAX + 1];
element e[2 * NMAX - 1 + 1];
element tree[4 * 2 * (NMAX - 1) + 1];
int tt[NMAX + 1];
vector <int> v[NMAX + 1];
void DFS(int nod, int height){
dimE++;
e[dimE].nod = nod;
e[dimE].height = height;
first[nod] = dimE;
last[nod] = dimE;
for(int i = 0; i < v[nod].size(); i++){
int X = v[nod][i];
DFS(X, height + 1);
dimE++;
e[dimE].nod = nod;
e[dimE].height = height;
last[nod] = dimE;
}
}
inline void buildEuler(){
DFS(1, 1); //stiu ca e radacina
}
element rezultant(element A, element B){
if(A.height <= B.height){
return A;
}
else {
return B;
}
}
void buildArbore(int node, int left, int right){
if(left == right){
tree[node] = e[left];
return;
}
int mid = left + (right - left) / 2;
buildArbore(node * 2, left, mid);
buildArbore(node * 2 + 1, mid + 1, right);
tree[node] = rezultant(tree[node * 2], tree[node * 2 + 1]);
}
int A, B; ///
element queryArbore(int node, int left, int right){
if(A <= left && right <= B){
return tree[node];
}
int mid = left + (right - left) / 2;
element rez1, rez2;
int OK1 = 0, OK2 = 0;
if(A <= mid){
rez1 = queryArbore(node * 2, left, mid);
OK1 = 1;
}
if(B >= mid + 1){
rez2 = queryArbore(node * 2 + 1, mid + 1, right);
OK2 = 1;
}
if(OK2 == 0){
return rez1;
}
else if(OK1 == 0){
return rez2;
}
else {
return rezultant(rez1, rez2);
}
}
int main()
{
int N, M;
fin >> N >> M;
for(int i = 2; i <= N; i++){
fin >> tt[i];
v[ tt[i] ].push_back(i);
}
buildEuler();
buildArbore(1, 1, dimE);
for(int q = 1; q <= M; q++){
//printf("q = %d\n", q);
int a, b;
fin >> a >> b;
if(a > b){
swap(a, b);
}
A = first[a];
B = first[b];
fout << queryArbore(1, 1, dimE).nod << "\n";
//printf("\n");
}
return 0;
}