Pagini recente » Cod sursa (job #3128861) | Cod sursa (job #197099) | Cod sursa (job #729685) | Cod sursa (job #3177676) | Cod sursa (job #3002567)
#include <bits/stdc++.h>
#define FUG fin.close(); fout.close(); exit(0);
using namespace std;
string const& task("lca");
ifstream fin((task + ".in").c_str());
ofstream fout((task + ".out").c_str());
int const N(1e5 + 5), LN(17);
int dad[LN][N], l2[N], p2[LN], n, m, lvl[N];
vector<int> g[N];
inline void Init() {
for (int i = 2; i < N; ++i)
l2[i] = l2[i / 2] + 1;
p2[0] = 1;
for (int i = 1; i < LN; ++i)
p2[i] = p2[i - 1] * 2;
}
inline void DFS(int const& x = 1) {
for (int l = 1; l < LN; ++l) {
dad[l][x] = dad[l - 1][dad[l - 1][x]];
if (!dad[l][x]) break;
}
for (int const& y : g[x]) {
dad[0][y] = x;
lvl[y] = lvl[x] + 1;
DFS(y);
}
}
inline int LCA(int const& a, int const& b) {
int x = a, y = b;
if (lvl[x] < lvl[y])
swap(x, y);
for (int l = l2[lvl[x] - lvl[y] + 1]; l >= 0; --l)
if (lvl[x] - p2[l] >= lvl[y])
x = dad[l][x];
if (x == y) return x;
for (int l = l2[lvl[x] + 1]; l >= 0; --l)
if (dad[l][x] != dad[l][y]) {
x = dad[l][x];
y = dad[l][y];
}
return dad[0][x];
}
signed main() {
Init();
fin >> n >> m;
for (int i = 2; i <= n; ++i) {
int x;
fin >> x;
g[x].emplace_back(i);
}
DFS();
while (m--) {
int x, y;
fin >> x >> y;
fout << LCA(x, y) << '\n';
}
FUG
}