Pagini recente » Cod sursa (job #2346249) | Cod sursa (job #594930) | Cod sursa (job #657381) | Cod sursa (job #1801156) | Cod sursa (job #2080790)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream f ("lca.in");
ofstream g ("lca.out");
const int NMAX = 100000 + 1;
const int PMAX = 18;
int n, m;
int e, ind;
vector <int> graf[NMAX];
int eticheta_nod[NMAX];
int prima_aparitie[NMAX];
int logaritm[NMAX];
int rmq[PMAX][2 * NMAX];
void citeste() {
f >> n >> m;
int t;
for (int i = 2; i <= n; i++) {
f >> t;
graf[t].push_back(i);
}
}
void liniarizeaza(int nod) {
int eticheta = ++e;
eticheta_nod[eticheta] = nod;
prima_aparitie[nod] = ++ind;
rmq[0][ind] = e;
int l = graf[nod].size();
for (int i = 0; i < l; i++) {
liniarizeaza(graf[nod][i]);
rmq[0][++ind] = eticheta;
}
}
void init_rmq() {
for (int i = 2; i <= ind; i++) logaritm[i] = logaritm[i / 2] + 1;
for (int p = 1; (1 << p) <= ind; p++) {
int l = 1 << (p - 1);
for (int i = 1; i <= ind - l + 1; i++) {
rmq[p][i] = min(rmq[p - 1][i], rmq[p - 1][i + l]);
}
}
}
int query(int a, int b) {
if (a > b) swap(a, b);
int l = b - a + 1;
int p = logaritm[l];
return min(rmq[p][a], rmq[p][b - (1 << p) + 1]);
}
void rezolva() {
int a, b;
for (int i = 1; i <= m; i++) {
f >> a >> b;
g << eticheta_nod[query(prima_aparitie[a], prima_aparitie[b])] << '\n';
}
}
int main() {
citeste();
liniarizeaza(1);
init_rmq();
rezolva();
return 0;
}