Pagini recente » Cod sursa (job #2665779) | Cod sursa (job #1960828) | Cod sursa (job #1290739) | Cod sursa (job #1556312)
#include <algorithm>
#include <cstring>
#include <fstream>
using namespace std;
const int NMAX = 100005;
vector<int> G[NMAX];
int father[NMAX], level[NMAX];
int euler[2 * NMAX], first[NMAX], last[NMAX], euLevel[2 * NMAX], eu;
int rmq[20][2 * NMAX], plog[2 * NMAX];
void dfs(int node, int prev) {
level[node] = level[prev] + 1;
euler[++eu] = node;
euLevel[eu] = level[node];
first[node] = eu;
for (int p: G[node]) {
dfs(p, node);
euler[++eu] = node;
euLevel[eu] = level[node];
}
last[node] = eu;
}
void buildRMQ() {
for (int i = 2; i <= eu; ++i) {
plog[i] = plog[i / 2] + 1;
}
for (int i = 1; i <= eu; ++i)
rmq[0][i] = i;
for (int k = 1; (1 << k) <= eu; ++k) {
int y = 1 << k - 1;
for (int i = 1; i + (1 << k) - 1 <= eu; ++i) {
rmq[k][i] = rmq[k - 1][i];
if (euLevel[rmq[k - 1][i + y]] < euLevel[rmq[k][i]]) {
rmq[k][i] = rmq[k - 1][i + y];
}
}
}
}
int lca(int x, int y) {
x = first[x];
y = first[y];
if (x > y) swap(x, y);
int diff = plog[y - x + 1];
int ret = rmq[diff][x];
if (euLevel[rmq[diff][y - (1 << diff) + 1]] < euLevel[ret]) {
ret = rmq[diff][y - (1 << diff) + 1];
}
return euler[ret];
}
int main() {
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, q;
fin >> n >> q;
for (int i = 2; i <= n; ++i) {
int x;
fin >> x;
G[x].push_back(i);
father[i] = x;
}
dfs(1, 0);
buildRMQ();
while (q-- > 0) {
int x, y;
fin >> x >> y;
fout << lca(x, y) << '\n';
}
fin.close();
fout.close();
}