Pagini recente » Utilizatori inregistrati la preONI 2007, Runda 3, Clasele 11-12 | Cod sursa (job #993588) | Cod sursa (job #2978352) | Cod sursa (job #1482186) | Cod sursa (job #2956902)
#include <cstdio>
#include <vector>
#include <cmath>
#include <time.h>
#include <algorithm>
#define NMAX 1000005
#define RMQ_SIZE 25
using namespace std;
vector <int> G[NMAX];
int lvl[NMAX], eu[2 * NMAX], lg[2 * NMAX], st[2 * NMAX], rmq_mat[RMQ_SIZE][2 * NMAX], n_eu;
void dfs(int nod, int lv) {
eu[++n_eu] = nod;
lvl[n_eu] = lv;
st[nod] = n_eu;
for(int i = 0; i < G[nod].size();i++) {
dfs(G[nod][i], lv + 1);
eu[++n_eu] = nod;
lvl[n_eu] = lv;
}
}
void rmq() {
int i, j, l;
for (i = 2; i <= n_eu; i++)
lg[i] = lg[i >> 1] + 1;
for (i = 1; i <= n_eu; i++)
rmq_mat[0][i] = i;
for (i = 1; (1 << i) < n_eu; i++) {
l = 1 << i;
for (j = 1; j + l <= n_eu; j++) {
rmq_mat[i][j] = rmq_mat[i - 1][j];
if (lvl[rmq_mat[i - 1][j + (l >> 1)]] < lvl[rmq_mat[i][j]])
rmq_mat[i][j] = rmq_mat[i - 1][j + (l >> 1)];
}
l = 1<<i;
}
}
inline int query(int a, int b) {
a = st[a];
b = st[b];
if (a > b)
swap(a, b);
if (lvl[rmq_mat[lg[b - a + 1]][a]] < lvl[rmq_mat[lg[b - a + 1]][b - (1 << lg[b - a + 1]) + 1]])
return eu[rmq_mat[lg[b - a + 1]][a]];
return eu[rmq_mat[lg[b - a + 1]][b - (1 << lg[b - a + 1]) + 1]];
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int n, m, i, a, b;
scanf("%d%d", &n, &m);
for (i = 1; i < n; i++) {
scanf("%d", &a);
G[a].push_back(i + 1);
}
dfs(1, 1);
rmq();
for (i = 0; i < m; i++) {
scanf("%d%d", &a, &b);
printf("%d\n", query(a, b));
}
return 0;
}