Pagini recente » Cod sursa (job #2758923) | Cod sursa (job #3178623) | Cod sursa (job #536553) | Cod sursa (job #2731522) | Cod sursa (job #2677962)
#ifdef LOCAL
#include <debug.hpp>
#else
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,tune=native")
#define debug(...)
#endif
#include <bits/stdc++.h>
using namespace std;
struct Lift {
struct Data { int par, link, dep; };
vector<Data> T;
int Add(int par) {
int ret = T.size();
if (par == -1) T.push_back(Data{-1, ret, 0});
else {
int link = par, a1 = T[par].link, a2 = T[a1].link;
if (2 * T[a1].dep == T[a2].dep + T[par].dep)
link = a2;
T.push_back(Data{par, link, T[par].dep + 1});
}
return ret;
}
int Kth(int node, int k) {
int seek = T[node].dep - k;
if (seek < 0) return -1;
while (T[node].dep > seek)
node = (T[T[node].link].dep >= seek)
? T[node].link : T[node].par;
return node;
}
int LCA(int a, int b) {
if (T[a].dep < T[b].dep) swap(a, b);
while (T[a].dep > T[b].dep)
a = (T[T[a].link].dep >= T[b].dep)
? T[a].link : T[a].par;
while (a != b) {
if (T[a].dep == 0) return -1;
if (T[a].link != T[b].link)
a = T[a].link, b = T[b].link;
else a = T[a].par, b = T[b].par;
}
return a;
}
};
void DFS(int node, int par,
vector<vector<int>>& graph,
Lift& L, vector<int> &atob,
vector<int>& btoa) {
int nnode = L.Add(par);
atob[node] = nnode;
btoa[nnode] = node;
for (auto vec : graph[node])
DFS(vec, nnode, graph, L, atob, btoa);
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
ifstream cin("lca.in");
ofstream cout("lca.out");
int n, m; cin >> n >> m;
vector<vector<int>> graph(n);
for (int i = 1; i < n; ++i) {
int par; cin >> par; --par;
graph[par].push_back(i);
}
vector<int> atob(n, -1), btoa(n, -1);
Lift L;
DFS(0, -1, graph, L, atob, btoa);
for (int i = 0; i < m; ++i) {
int a, b; cin >> a >> b; --a; --b;
cout << 1 + btoa[L.LCA(atob[a], atob[b])] << '\n';
}
return 0;
}