Pagini recente » Cod sursa (job #3303) | Cod sursa (job #2477640) | Cod sursa (job #107153) | Cod sursa (job #2058857) | Cod sursa (job #1921396)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int LGMAX = 17;
const int NMAX = 1e5 + 1;
int n, q;
int a[NMAX];
int rmq[LGMAX][NMAX];
int pos[NMAX], lg[NMAX];
pair<int, int> euler[3 * NMAX]; // node, level
int eulerSZ;
vector<vector<int> > v;
inline void read() {
fin >> n >> q;
v = vector<vector<int> >(n + 1);
int x;
for (int i = 2; i <= n; ++i) {
fin >> x;
v[x].push_back(i);
}
}
void dfs(int node, int lv) {
euler[++eulerSZ] = {node, lv};
pos[node] = eulerSZ;
for (const int& other: v[node]) {
dfs(other, lv + 1);
euler[++eulerSZ] = {node, lv};
}
}
inline void preProcess() {
for (int i = 2; i <= eulerSZ; ++i)
lg[i] = lg[i / 2] + 1;
for (int i = 1; i <= eulerSZ; ++i)
rmq[0][i] = i;
}
inline void getRMQ() {
preProcess();
int len;
for (int i = 1; (1 << i) <= eulerSZ; ++i) {
for (int j = 1; j + (1 << i) - 1 <= eulerSZ; ++j) {
len = 1 << (i - 1);
if (euler[rmq[i - 1][j]].second < euler[rmq[i - 1][j + len]].second)
rmq[i][j] = rmq[i - 1][j];
else
rmq[i][j] = rmq[i - 1][j + len];
}
}
}
inline int getLCA(int x, int y) {
int a = pos[x], b = pos[y];
if (a > b)
swap(a, b);
int d = b - a + 1;
int len = lg[d];
int rem = d - (1 << len);
if (euler[rmq[len][a]].second < euler[rmq[len][a + rem]].second)
return euler[rmq[len][a]].first;
else
return euler[rmq[len][a + rem]].first;
}
int main()
{
read();
dfs(1, 0);
getRMQ();
int x, y;
for (int i = 1; i <= q; ++i) {
fin >> x >> y;
fout << getLCA(x, y) << '\n';
}
return 0;
}