Pagini recente » Autentificare | Cod sursa (job #1916814) | Cod sursa (job #3164044) | Cod sursa (job #2428827) | Cod sursa (job #1365611)
#include <iostream>
#include <fstream>
#include <vector>
#define nmax 100005
using namespace std;
int n, m;
bool viz[nmax];
int Euler[2*nmax], Exp[2*nmax], Min[19][2*nmax], Poz[19][2*nmax], Nivel[nmax], P[nmax];
vector <int> G[nmax];
void euler(int nod, int niv) {
Euler[++Euler[0]] = nod;
Nivel[nod] = niv;
P[nod] = Euler[0];
for (int i = 0; i < G[nod].size(); i++)
euler(G[nod][i], niv + 1),
Euler[++Euler[0]] = nod;
}
void preprocess() {
Exp[1] = 0;
for (int i = 2; i <= Euler[0]; i++)
Exp[i] = Exp[i/2] + 1;
for (int i = 1; i <= Euler[0]; i++) {
Min[0][i] = Nivel[Euler[i]];
Poz[0][i] = i;
}
for (int i = 1; i <= Exp[Euler[0]]; i++)
for (int j = 1; j <= Euler[0] - (1<<i) + 1; j++) {
int st = j;
int dr = st + (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];
}
}
int main() {
ifstream fin("lca.in");
ofstream fout("lca.out");
fin >> n >> m;
for (int i = 2; i <= n; i++) {
int x;
fin >> x;
G[x].push_back(i);
}
euler(1, 1);
preprocess();
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 = Euler[Poz[k][x]];
x = y - (1<<k) + 1;
if (rez > Min[k][x])
lca = Euler[Poz[k][x]];
fout << lca << "\n";
}
fin.close();
fout.close();
return 0;
}