Pagini recente » Cod sursa (job #329050) | Cod sursa (job #1187864) | Cod sursa (job #2811595) | Cod sursa (job #3286375) | Cod sursa (job #3169531)
#include <bits/stdc++.h>
using namespace std;
string to_string(const string &s) {
return '"' + s + '"';
}
string to_string(bool b) {
return b ? "true" : "false";
}
template <typename A, typename B>
string to_string(const pair<A, B> &p) {
return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
template <typename T>
string to_string(const T &v) {
string s = "{";
bool first = true;
for (const auto &it : v) {
if (!first)
s += ", ";
else
first = false;
s += to_string(it);
}
return s += "}";
}
void debug_out() {
cerr << endl;
}
template <typename T, typename... Args>
void debug_out(const T &first, const Args&... rest) {
cerr << to_string(first) << " ";
debug_out(rest...);
}
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
namespace LCA {
ifstream cin("lca.in");
ofstream cout("lca.out");
int n;
int q;
int k;
int tmp;
vector<int> lg;
vector<int> ap;
vector<int> h;
vector<int> euler;
vector<vector<int>> mn;
vector<vector<int>> v;
void read() {
cin >> n >> q;
v.resize(n + 1);
for (int i = 2; i <= n; ++i) {
int x;
cin >> x;
v[x].push_back(i);
}
}
void dfs(int nod = 1, int papa = 0) {
ap[nod] = tmp;
euler[tmp++] = nod;
for (auto it : v[nod]) {
if (it == papa)
continue;
h[it] = h[nod] + 1;
dfs(it);
euler[tmp++] = nod;
}
}
int get_min(int x, int y) {
return (h[x] < h[y]) ? x : y;
}
void build() {
h.resize(n + 1);
ap.resize(n + 1);
euler.resize(2 * n - 1);
tmp = 0;
h[1] = 0;
dfs();
lg.resize(euler.size() + 1);
lg[0] = 0;
for (size_t i = 1; i < lg.size(); ++i)
lg[i] = lg[i >> 1] + 1;
// maybe alloc this on bss
mn.resize(euler.size());
k = int(lg[euler.size()]);
for (size_t i = 0; i < mn.size(); ++i) {
mn[i].resize(k + 1);
mn[i][0] = euler[i];
}
for (int j = 1; j <= k; ++j) {
for (size_t i = 0; i < mn.size(); ++i) {
mn[i][j] = get_min(mn[i][j - 1], mn[min(i + (1 << (j - 1)), mn.size() - 1)][j - 1]);
}
}
}
int query(int x, int y) {
x = ap[x]; y = ap[y];
int df = y - x + 1;
return get_min(mn[x][lg[df]], mn[y + 1 - (1 << lg[df])][lg[df]]);
}
void print_queries() {
for (int i = 1; i <= q; ++i) {
int x, y;
cin >> x >> y;
cout << query(x, y) << "\n";
}
}
}
int main() {
LCA::read();
LCA::build();
LCA::print_queries();
return 0;
}