Pagini recente » Cod sursa (job #1295079) | Monitorul de evaluare | Monitorul de evaluare | Cod sursa (job #934476) | Cod sursa (job #1640198)
#include <cstdio>
#include <vector>
using namespace std;
const int NMAX = 100000;
const int LGMAX = 17;
int n, m;
int t[1 + NMAX];
vector <int> v[1 + NMAX];
int eul;
int d[2 * NMAX];
int h[2 * NMAX];
int prim[1 + NMAX];
int lg[2 * NMAX];
int rmq[1 + LGMAX][1 + 2 * NMAX];
void dfs(int nod, int niv) {
++eul;
d[eul] = nod;
h[eul] = niv;
prim[nod] = eul;
for (int i = 0; i < v[nod].size(); ++i) {
dfs(v[nod][i], niv + 1);
++eul;
d[eul] = nod;
h[eul] = niv;
}
}
void calc() {
dfs(1, 1);
for (int i = 2; i <= eul; ++i)
lg[i] = lg[i >> 1] + 1;
for (int j = 1; j <= eul; ++j)
rmq[0][j] = j;
for (int i = 1, lung = 2; lung <= eul; ++i, lung <<= 1) {
for (int j = 1; j + lung <= eul; ++j) {
if (h[rmq[i - 1][j]] < h[rmq[i - 1][j + (lung >> 1)]])
rmq[i][j] = rmq[i - 1][j];
else
rmq[i][j] = rmq[i - 1][j + (lung >> 1)];
}
}
}
int lca(int x, int y) {
if (prim[x] > prim[y]) {
int aux = x;
x = y;
y = aux;
}
int l = lg[prim[y] - prim[x] + 1];
if (h[rmq[l][prim[x]]] < h[rmq[l][prim[y] - (1 << l) + 1]])
return d[rmq[l][prim[x]]];
else
return d[rmq[l][prim[y] - (1 << l) + 1]];
}
////
const int LBUFF = 500000;
char buff[LBUFF];
int pz = LBUFF - 1;
int getInt() {
while (buff[pz] < '0' || buff[pz] > '9') {
++pz;
if (pz == LBUFF) {
pz = 0;
fread(buff, 1, LBUFF, stdin);
}
}
int num = 0;
while (buff[pz] >= '0' && buff[pz] <= '9') {
num = num * 10 + buff[pz] - '0';
++pz;
if (pz == LBUFF) {
pz = 0;
fread(buff, 1, LBUFF, stdin);
}
}
return num;
}
////
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
n = getInt();//scanf("%d%d", &n, &m);
m = getInt();
for (int i = 2; i <= n; ++i) {
t[i] = getInt();//scanf("%d", &t[i]);
v[t[i]].push_back(i);
}
calc();
int x, y;
while(m--) {
x = getInt();//scanf("%d%d", &x, &y);
y = getInt();
printf("%d\n", lca(x, y));
}
return 0;
}