Pagini recente » Cod sursa (job #3250021) | Cod sursa (job #2673171) | Cod sursa (job #2825275) | Cod sursa (job #2961910) | Cod sursa (job #1363761)
#include <fstream>
#include <vector>
#define MAXN 100000
#define LOG 21
using namespace std;
typedef vector <int> graf;
graf Arb[MAXN + 1];
int E[(2 * MAXN) + 1], L[(2 * MAXN) + 1], Ind[MAXN + 1];
int RMQ[LOG + 1][MAXN + 1];
int lg[(2 * MAXN) + 1];
int nrn = 0;
int minim(int x, int y) {
return (x < y ? x : y);
}
int maxim(int x, int y) {
return (x > y ? x : y);
}
void EULER(int node, int lvl) {
E[nrn] = node;
if (Ind[node] == -1)
Ind[node] = nrn;
L[nrn++] = lvl;
for (graf :: iterator it = Arb[node].begin() ; it != Arb[node].end() ; ++it) {
EULER(*it, lvl + 1);
E[nrn] = node;
L[nrn++] = lvl;
}
}
int query(int x, int y) {
int diff = y - x + 1, l = lg[diff];
int sol = RMQ[l][x];
int df = diff - (1 << l);
if (L[sol] > L[RMQ[l][x + df]])
sol = RMQ[l][x + df];
return E[sol];
}
int main () {
ifstream cin("lca.in");
ofstream cout("lca.out");
int n, m;
cin >> n >> m;
for (int i = 2 ; i <= n ; ++i) {
int d;
cin >> d;
Arb[d].push_back(i);
}
for (int i = 1 ; i <= n ; ++i)
Ind[i] = -1;
EULER(1, 0);
lg[1] = 0;
for (int i = 2 ; i <= nrn ; ++i)
lg[i] = 1 + lg[i / 2];
for (int i = 0 ; i < nrn ; ++i)
RMQ[0][i] = i;
for (int j = 1 ; j <= lg[nrn] ; ++j)
for (int i = 0 ; (i + (1 << j) - 1) < nrn ; ++i) {
if (L[RMQ[j - 1][i]] < L[RMQ[j - 1][i + (1 << (j - 1))]])
RMQ[j][i] = RMQ[j - 1][i];
else
RMQ[j][i] = RMQ[j - 1][i + (1 << (j - 1))];
}
for (int i = 0 ; i < m ; ++i) {
int x, y;
cin >> x >> y;
cout << query(minim(Ind[x], Ind[y]), maxim(Ind[x], Ind[y])) << "\n";
}
return 0;
}