Pagini recente » Cod sursa (job #2733730) | Cod sursa (job #1487446) | Cod sursa (job #2982357) | Istoria paginii runda/tema_lee/clasament | Cod sursa (job #1320817)
#include <iostream>
#include <fstream>
#include <vector>
#define nmax 100005
#define inf 1<<30
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m;
int k = 0;
int T[nmax], E[2*nmax], Min[20][2*nmax], Nivel[nmax], Poz[20][2*nmax], Exp[2*nmax], P[nmax];
vector <int> node[nmax];
bool viz[nmax];
void citire() {
fin >> n >> m;
for (int i = 1; i < n; i++) {
fin >> T[i+1];
node[T[i+1]].push_back(i+1);
}
}
void euler(int nod, int niv) {
E[++E[0]] = nod;
Nivel[nod] = niv;
P[nod] = E[0];
for (int i = 0; i < node[nod].size(); i++){
euler(node[nod][i], niv + 1);
E[++E[0]] = nod;
}
}
void preprocesare() {
for (int i = 1; i <= E[0]; i++)
Min[0][i] = Nivel[E[i]],
Poz[0][i] = i;
for (int i = 1; i <= 18; i++)
for (int j = 1; j <= (E[0] - (1<<i) + 1); j++) {
int st = j;
int dr = j + (1<<i) - 1;
int mid = dr - (1<<(i-1)) + 1;
Min[i][j] = Min[i-1][st];
Poz[i][j] = Poz[i-1][st];
if (Min[i][j] > Min[i-1][mid])
Min[i][j] = Min[i-1][mid],
Poz[i][j] = Poz[i-1][mid];
}
}
void solve() {
euler(1, 1);
preprocesare();
Exp[1] = 0;
for (int i = 2; i <= E[0]; i++)
Exp[i] = Exp[i/2] + 1;
for (int i = 1; i <= m; i++) {
int x, y;
fin >> x >> y;
x = P[x], y = P[y];
if (x > y) swap(x, y);
int l = y - x + 1;
int k = Exp[l];
int rez = Min[k][x];
int lca = E[ Poz[k][x] ];
x = y - (1<<k) + 1;
if (rez > Min[k][x]) {
rez = Min[k][x];
lca = E[ Poz[k][x] ];
}
fout << lca << "\n";
}
}
int main() {
citire();
solve();
fin.close();
fout.close();
return 0;
}