Pagini recente » Cod sursa (job #2471946) | Cod sursa (job #2684076) | Rezultatele filtrării | Cod sursa (job #2532968) | Cod sursa (job #2287641)
#include <iostream>
#include <vector>
#define nmax 100010
using namespace std;
int n, q, c_time, nr = 0;
int v[2 * nmax], pos[nmax], lvl[nmax], e_time[nmax];
int rmq[20][2 * nmax];
vector <int> graph[nmax];
void dfs1(int node, int p)
{
lvl[node] = lvl[p] + 1;
e_time[node] = ++c_time;
for (int i = 0; i < graph[node].size(); i++)
if (graph[node][i] != p) dfs1(graph[node][i], node);
}
void dfs2(int node, int p)
{
nr++;
pos[node] = nr;
rmq[0][nr] = node;
for (int i = 0; i < graph[node].size(); i++)
if (graph[node][i] != p) {
dfs2(graph[node][i], node);
nr++;
rmq[0][nr] = node;
}
}
void my_swap(int &a, int &b) { int aux = a; a = b; b = aux; }
int lca(int l, int r)
{
l = pos[l];
r = pos[r];
if (l > r) my_swap(l, r);
int aux = v[r - l + 1];
int p = (1 << aux);
if (lvl[rmq[aux][l]] < lvl[rmq[aux][r - p + 1]]) return rmq[aux][l]; else
return rmq[aux][r - p + 1];
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
scanf("%d %d", &n, &q);
for (int i = 2; i <= n; i++) {
int x;
scanf("%d", &x);
graph[x].push_back(i);
graph[i].push_back(x);
}
dfs1(1, 0); // time when entered each node
dfs2(1, 0);
v[1] = 0;
for (int i = 2; i <= nr; i++) v[i] = v[i / 2] + 1;
// build rmq
for (int i = 1; (1 << i) <= nr; i++) {
int aux = (1 << (i - 1));
for (int j = 1; j + 2 * aux - 1 <= nr; j++)
if (lvl[rmq[i - 1][j]] < lvl[rmq[i - 1][j + aux]]) rmq[i][j] = rmq[i - 1][j]; else
rmq[i][j] = rmq[i - 1][j + aux];
}
for (int i = 1; i <= q; i++) {
int x, y;
scanf("%d %d", &x, &y);
printf("%d\n", lca(x, y));
}
return 0;
}