Pagini recente » Cod sursa (job #609802) | Cod sursa (job #530200) | Cod sursa (job #1611286) | Cod sursa (job #2548125) | Cod sursa (job #2124401)
#include <fstream>
#include <vector>
#define MAXN 100005
#define inf 0x3f3f3f3f
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector <int> graph[MAXN];
int nn, n, m;
int fr[MAXN], niv[MAXN];
int log[MAXN], lin, mm;
struct str{
int val, poz;
};
str rmq[22][4000001];
inline void DFS(int nod, int parinte) {
rmq[0][++nn] = {niv[nod], nod};
if (!fr[nod])
fr[nod] = nn;
for (auto x : graph[nod]) {
if (x != parinte) {
niv[x] = niv[nod] + 1;
DFS(x, nod);
}
// rmq[0][++nn] = {niv[nod], nod};
}
rmq[0][++nn] = {niv[parinte], parinte};
}
inline void RMQ() {
mm = log[nn];
for (int i = 1; i <= mm; i++) {
for (int j = 1; (j + (1 << (i - 1))) <= nn; j++) {
if (rmq[i - 1][j].val < rmq[i - 1][j + (1 << (i - 1))].val)
rmq[i][j] = rmq[i - 1][j];
else
rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
}
}
}
inline int Query(int a, int b) {
// fout << fr[a] << " " << fr[b];
lin = log[b - a + 1];
if (rmq[lin][a].val < rmq[lin][b - (1 << lin) + 1].val)
return rmq[lin][a].poz;
else
return rmq[lin][b - (1 << lin) + 1].poz;
}
inline void Read() {
int x;
fin >> n >> m;
for (int i = 2; i <= n; i++) {
fin >> x;
graph[x].push_back(i);
graph[i].push_back(x);
}
niv[1] = 1;
DFS(1, 1);
for (int i = 2; i <= nn; i++)
log[i] = log[i / 2] + 1;
RMQ();
int y;
for (int i = 1; i <= m; i++) {
fin >> x >> y;
fout << Query(min(fr[x], fr[y]), max(fr[x], fr[y])) << "\n";
}
}
int main () {
Read();
fin.close(); fout.close(); return 0;
}