Pagini recente » Cod sursa (job #2837869) | Cod sursa (job #2920414) | Cod sursa (job #2128429) | Cod sursa (job #2952457) | Cod sursa (job #1374008)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream f ("lca.in");
ofstream g ("lca.out");
const int NMAX = 100000 + 1;
const int LOGMAX = 18 + 1;
int n, m, nre, e;
int eticheta[NMAX], etichetat[NMAX];
int prima[NMAX], ultima[NMAX];
int log2[2 * NMAX];
int rmq[LOGMAX][2 * NMAX];
vector <int> graf[NMAX];
void citeste() {
int t;
f >> n >> m;
for (int i = 2; i <= n; i++) {
f >> t;
graf[t].push_back(i);
}
}
void liniarizeaza(int nod) {
int l = graf[nod].size(), fiu;
eticheta[nod] = ++e;
etichetat[e] = nod;
//euler[++nre] = nod;
rmq[0][++nre] = eticheta[nod];
prima[nod] = ultima[nod] = nre;
for (int i = 0; i < l; i++) {
fiu = graf[nod][i];
liniarizeaza(fiu);
//euler[++nre] = nod;
rmq[0][++nre] = eticheta[nod];
ultima[nod] = nre;
}
}
void precalculeaza() {
int l;
for (int i = 2; i <= nre; i++) log2[i] = log2[i / 2] + 1;
for (int i = 1; (1 << i) <= nre; i++) {
l = 1 << (i - 1);
for (int j = 1; j <= nre - l + 1; j++)
rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + l]); //, cout << rmq[i][j] << ' ';
}
}
inline int lca(int a, int b) {
a = prima[a];
b = prima[b];
if (a > b) switch(a, b);
int l = log2[b - a + 1];
int secv1 = a, secv2 = b - (1 << l) + 1;
return etichetat[min(rmq[l][secv1], rmq[l][secv2])];
}
void rezolva() {
int a, b;
while(m--) {
f >> a >> b;
g << lca(a, b) << '\n';
}
}
int main() {
citeste();
liniarizeaza(1);
precalculeaza();
rezolva();
return 0;
}