Pagini recente » Cod sursa (job #1472728) | Cod sursa (job #1834068) | Cod sursa (job #2611044) | Cod sursa (job #2866714) | Cod sursa (job #2374467)
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <utility>
#include <cmath>
#include <string>
#include <cstring>
#include <set>
#include <queue>
#include <map>
#include <stack>
#include <iomanip>
#define ll long long
#define lsb(x) (x & -x)
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
void dfs(int node, vector<int> &h, vector<int> &euler, const vector<vector<int>> &g) {
euler.push_back(node);
for(auto it : g[node]) {
h[it] = h[node] + 1;
dfs(it, h, euler, g);
euler.push_back(node);
}
}
int main() {
int n, q;
in >> n >> q;
vector<vector<int>> g(n + 1);
for(int i = 2; i <= n; i ++) {
int x;
in >> x;
g[x].push_back(i);
}
vector<int> euler;
vector<int> h(n + 1, 0);
h[1] = 1;
dfs(1, h, euler, g);
int m = euler.size();
vector<int> lg(m + 1, 0);
for(int i = 2; i <= m; i ++)
lg[i] = 1 + lg[i >> 1];
vector<vector<int>> rmq(lg[m] + 2, vector<int> (m, 0));
vector<int> firstpos(n + 1, 0);
for(int i = 0; i < m; i ++) {
rmq[0][i] = euler[i];
firstpos[euler[i]] = i;
}
for(int i = 1; i <= lg[m]; i ++) {
int p = (1 << (i - 1));
for(int j = 0; j + (1 << i) - 1 < m; j ++)
if(h[rmq[i - 1][j]] < h[rmq[i - 1][j + p]])
rmq[i][j] = rmq[i - 1][j];
else
rmq[i][j] = rmq[i - 1][j + p];
}
while(q --) {
int a, b;
in >> a >> b;
a = firstpos[a];
b = firstpos[b];
if(a > b)
swap(a, b);
int len = b - a + 1;
int ans;
if(h[rmq[lg[len]][a]] < h[rmq[lg[len]][b - (1 << lg[len]) + 1]])
ans = rmq[lg[len]][a];
else
ans = rmq[lg[len]][b - (1 << lg[len]) + 1];
out << ans << "\n";
}
return 0;
}