Pagini recente » Cod sursa (job #2895329) | Cod sursa (job #199313) | Cod sursa (job #343339) | Cod sursa (job #2935306) | Cod sursa (job #2796913)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
#define MAXN 100001
#define MAXLOGN 20
int n, m, nodes[2*MAXN+1], depth[2*MAXN+1], last[MAXN], current_position = 0, a[2*MAXN+1][MAXLOGN], b[2*MAXN+1][MAXLOGN];
vector<vector<int>> children;
void pre_process_rmq(){
for(int i=1; i<current_position; i++)
a[i][0] = depth[i];
for(int j=1; j<MAXLOGN; j++)
for(int i=1; i<= current_position - (1<<j) + 1; i++){
a[i][j] = min(a[i][j-1], a[i+(1<<j)][j-1]);
}
}
void citire(){
fin >> n >> m;
children = vector<vector<int>> (n+1);
for(int i=1; i<n; i++){
int father;
fin >> father;
children[father].push_back(i+1);
}
}
void dfs(int node, int node_depth){
nodes[current_position] = node;
depth[current_position] = node_depth;
last[node] = current_position;
current_position++;
for(auto child: children[node]){
dfs(child, node_depth + 1);
nodes[current_position] = node;
depth[current_position] = node_depth;
last[node] = current_position;
current_position++;
}
}
int main(){
citire();
// EULERIAN TOUR
dfs(1, 0);
// nodes[] -> nodes from Eulerian Tour
// depth[] -> depth for each node of nodes[]
// last[] -> last position of each node in Eulerian Tour
pre_process_rmq();
for(int ind=1; ind<=m; ind++){
int node_st, node_dr, st, dr, length, logg, sol;
fin >> node_st >> node_dr;
st = min(last[node_st], last[node_dr]) - 1;
dr = max(last[node_st], last[node_dr]) - 1 ;
length = dr-st+1;
logg = log2(length);
sol = min(a[st][logg], a[dr-(1<<logg)+1][logg]);
for(int i=st;i<=dr;i++){
if(depth[i] == sol) {fout << nodes[i] << '\n';break;}
}
}
return 0;
}