Pagini recente » Cod sursa (job #2849666) | Cod sursa (job #586684) | Cod sursa (job #740624) | Cod sursa (job #2675168) | Cod sursa (job #2292357)
#include <iostream>
#include <fstream>
#include <climits>
#include <vector>
#define DIM 200001
#define MAX_N 100001
#define MAX_Q 2000001
#define MAX_LOG_N 20
using namespace std;
int nodes, queries;
int LCA[MAX_LOG_N][DIM];
int log[DIM];
vector <int> edges[MAX_N];
int depth[DIM];
int first[MAX_N];
int eulerPath[MAX_N];
int kappa, level;
ifstream fin("lca.in");
ofstream fout("lca.out");
inline void precompute(){
log[0] = INT_MIN;
log[1] = 0;
for(int i = 2; i <= kappa; i ++)
log[i] = log[i / 2] + 1;
for(int i = 1; i <= kappa; i ++){
LCA[0][i] = i;
}
for(int i = 1; i <= log[kappa]; i ++)
for(int j = 1; j + (1 << i) <= kappa ; j ++){
int pow = (1 << (i - 1));
LCA[i][j] = LCA[i - 1][j];
if(depth[LCA[i][j]] > depth[ LCA[i - 1][j + pow] ])
LCA[i][j] = LCA[i - 1][j + pow];
}
}
inline void parseTree(){
fin >> nodes >> queries;
int x;
for(int i = 2; i <= nodes; i ++){
fin >> x;
edges[x].push_back(i);
}
}
void eulerWalk(int node){
level ++;
eulerPath[++ kappa] = node;
first[node] = kappa;
depth[kappa] = level;
for(std::vector<int>::iterator it = edges[node].begin(); it != edges[node].end(); it ++){
eulerWalk(*it);
eulerPath[++ kappa] = node;
depth[kappa] = level;
}
level --;
}
int queryHandler(int a, int b){
int sol;
a = first[a];
b = first[b];
if(a > b)
swap(a, b);
int L = log[b - a + 1];
sol = LCA[L][a];
if(depth[sol] > depth[ LCA[L][b - (1 << L) + 1] ])
sol = LCA[L][b - (1 << L) + 1];
return eulerPath[sol];
}
int main(){
parseTree();
level = 0;
eulerWalk(1);
precompute();
while(queries --){
int x, y;
fin >> x >> y;
fout << queryHandler(x, y) << "\n";
}
fin.close();
fout.close();
return 0;
}