Pagini recente » Cod sursa (job #1678814) | Cod sursa (job #1927832) | Cod sursa (job #2709010) | Cod sursa (job #2536546) | Cod sursa (job #2817917)
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 1e5,LOG = 20;
vector<int> fii[NMAX + 5];
int rmq[LOG + 5][4 * NMAX + 5],lg[4 * NMAX + 5],euler[NMAX * 4 + 5],level[NMAX * 4 + 5],first[NMAX * 4 + 5];
int n,cnt,ans,x,y,z;
void dfs(int node, int lvl) {
euler[++cnt] = node;
level[cnt] = lvl;
first[node] = cnt;
for (int i = 0;i < fii[node].size();i++) {
dfs(fii[node][i], lvl + 1);
euler[++cnt] = node;
level[cnt] = lvl;
}
}
void RMQ() {
rmq[1][0] = 1;
for (int i = 2;i <= cnt;i++) {
lg[i] = lg[(i >> 1)] + 1;
rmq[i][0] = i;
}
for (int j = 1;(1 << j) <= cnt;j++)
for (int i = 1;i + (1 << (j - 1)) <= cnt;i++) {
rmq[i][j] = rmq[i][j - 1];
if (level[rmq[i + (1 << (j - 1))][j - 1]] < level[rmq[i][j]])
rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
}
}
int lca(int a, int b) {
x = first[a];
y = first[b];
if (x > y)
swap(x, y);
z = lg[y - x + 1];
ans = rmq[x][z];
if (level[rmq[y - (1 << z) + 1][z]] < level[ans])
ans = rmq[y - (1 << z) + 1][z];
return euler[ans];
}
int main()
{
ifstream fin("lca.in");
ofstream fout("lca.out");
int m,a,b;
fin >> n >> m;
for (int i = 2;i <= n;i++) {
fin >> a;
fii[a].push_back(i);
}
dfs(1, 0);
RMQ();
for (int i = 0;i < m;i++) {
fin >> a >> b;
fout << lca(a, b) << '\n';
}
return 0;
}