Pagini recente » Cod sursa (job #2376884) | Cod sursa (job #238143) | Cod sursa (job #1706198) | Cod sursa (job #851678) | Cod sursa (job #2572682)
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <utility>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#define ll long long
using namespace std;
struct LCA {
vector<vector<int>> g;
int n;
vector<int> euler, h, firstpos; /// tb last pos??
int m;
vector<vector<int>> rmq;
vector<int> lg;
LCA(int _n, vector<vector<int>> &_g) {
n = _n;
g = _g;
firstpos.resize(n + 1, 0);
h.resize(n + 1, 0);
h[1] = 1;
dfs(1);
m = euler.size();
lg.resize(m + 1, 0);
for(int i = 2; i <= m; i ++)
lg[i] = 1 + lg[i >> 1];
rmq.resize(lg[m] + 1, vector<int> (m, 0));
for(int i = 0; i < m; i ++)
rmq[0][i] = euler[i];
for(int i = 1; i <= lg[m]; i ++)
for(int j = 0; j + (1 << (i - 1)) < m; j ++) {
int a = rmq[i - 1][j], b = rmq[i - 1][j + (1 << (i - 1))];
if(h[a] < h[b])
rmq[i][j] = a;
else
rmq[i][j] = b;
}
}
int query(int a, int b) {
a = firstpos[a];
b = firstpos[b];
if(a > b)
swap(a, b);
int dim = b - a + 1;
int x = rmq[lg[dim]][a], y = rmq[lg[dim]][b - (1 << lg[dim]) + 1];
if(h[x] > h[y])
swap(x, y);
return x;
}
void dfs(int node) {
firstpos[node] = euler.size();
euler.push_back(node);
for(auto it : g[node]) {
h[it] = h[node] + 1;
dfs(it);
euler.push_back(node);
}
}
};
int main() {
ifstream in("lca.in");
ofstream out("lca.out");
int n, m;
in >> n >> m;
vector<vector<int>> g(n + 1);
for(int i = 2; i <= n; i ++) {
int x;
in >> x;
g[x].push_back(i);
}
LCA lca(n, g);
while(m --) {
int x, y;
in >> x >> y;
out << lca.query(x, y) << "\n";
}
return 0;
}