Pagini recente » Cod sursa (job #1833006) | Cod sursa (job #2357955) | Cod sursa (job #1745610) | Cod sursa (job #109910) | Cod sursa (job #2773625)
#include <bits/stdc++.h>
#define NMAX 100001
#define MMAX 2000001
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int log_2[MMAX];
int first[MMAX];
int dp[MMAX][25];
vector<int> graph[NMAX];
struct node {
int euler, level;
}nodes[MMAX];
int k;
void dfs(int vertex, int depth) {
nodes[++k].euler = vertex;
nodes[k].level = depth;
first[vertex] = k;
for(auto x : graph[vertex]) {
dfs(x, depth + 1);
nodes[++k].euler = vertex;
nodes[k].level = depth;
}
}
void gen() {
int log = log_2[k];
for(int i = 1; i <= k; i++)
dp[i][0] = i;
for(int i = 1; i <= log; i++) {
for(int j = 1; j <= k; j++) {
if(j + (1 << i) > k)
break;
if(nodes[dp[j][i - 1]].level <= nodes[dp[j + (1 << (i - 1))][i - 1]].level)
dp[j][i] = dp[j][i - 1];
else
dp[j][i] = dp[j + (1 << (i - 1))][i - 1];
}
}
}
int get(int left, int right) {
if(left > right)
swap(left, right);
int dist = right - left + 1;
if(nodes[dp[left][log_2[dist]]].level <= nodes[dp[right - (1 << log_2[dist]) + 1][log_2[dist]]].level)
return nodes[dp[left][log_2[dist]]].euler;
return nodes[dp[right - (1 << log_2[dist]) + 1][log_2[dist]]].euler;
}
int main() {
int n, m;
fin >> n >> m;
for(int i = 2; i <= MMAX - 1; i++)
log_2[i] = log_2[i / 2]+1;
for(int i = 2; i <= n; i++) {
int x;
fin >> x;
graph[x].push_back(i);
}
dfs(1, 0);
gen();
for(int i = 1; i <= m; i++) {
int a, b;
fin >> a >> b;
fout << get(first[a], first[b]) << '\n';
}
}