Pagini recente » Cod sursa (job #1186372) | Cod sursa (job #761956) | Cod sursa (job #1041830) | Cod sursa (job #2170881) | Cod sursa (job #3200814)
#include <bits/stdc++.h>
using namespace std;
#define INFILE "lca.in"
#define OUTFILE "lca.out"
const int N_MAX = 1e5 + 5;
const int LOG_MAX = 10;
int n, queries;
int parent[LOG_MAX][N_MAX], depth[N_MAX];
vector<int> adj[N_MAX];
void generatingDepth(int node){
for(auto to : adj[node]){
depth[to] = depth[node] + 1;
generatingDepth(to);
}
}
void binaryLifting(){
for(int i = 1; i < LOG_MAX; ++i){
for(int j = 1; j <= n; ++j){
parent[i][j] = parent[i - 1][parent[i - 1][j]];
}
}
}
int findAncestor(int node, int numberOfAncestor){
if(numberOfAncestor >= (1 << LOG_MAX)) return 0;
for(int i = 0; i < LOG_MAX; ++i){
if(numberOfAncestor & (1 << i)) node = parent[i][node];
}
return node;
}
int lowestCommonAncestor(int node1, int node2){
if(depth[node1] < depth[node2]) swap(node1, node2);
node1 = findAncestor(node1, depth[node1] - depth[node2]);
if(node1 == node2) return node1;
for(int i = LOG_MAX - 1; i >= 0; --i){
if(parent[i][node1] != parent[i][node2]) node1 = parent[i][node1], node2 = parent[i][node2];
}
return parent[0][node1];
}
void solve(){
cin >> n >> queries;
for(int i = 2; i <= n; ++i){
cin >> parent[0][i];
adj[parent[0][i]].push_back(i);
}
depth[1] = 0;
generatingDepth(1);
binaryLifting();
for(int i = 0; i < queries; ++i){
int node1, node2; cin >> node1 >> node2; cout << lowestCommonAncestor(node1, node2) << '\n';
}
}
int main(){
ios_base::sync_with_stdio(false);
freopen(INFILE, "r", stdin);
freopen(OUTFILE, "w", stdout);
cin.tie(0), cout.tie(0);
solve();
return 0;
}