Pagini recente » Cod sursa (job #1471387) | Monitorul de evaluare | Cod sursa (job #601301) | Cod sursa (job #682471) | Cod sursa (job #2084850)
#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;
struct str{
int val, poz;
};
str rmq[22][MAXN * 5];
inline void DFS(int nod) {
rmq[0][++nn] = {niv[nod], nod};
// fout << nod << " ";
if (!fr[nod])
fr[nod] = nn;
for (auto x : graph[nod]) {
niv[x] = niv[nod] + 1;
DFS(x);
rmq[0][++nn] = {niv[nod], nod};
// fout << nod << " ";
}
rmq[0][++nn] = {niv[nod], nod};
// fout << nod << " ";
}
inline void RMQ() {
int mm = log[nn];
for (int i = 1; i <= mm; i++) {
for (int j = 1; (j + (1 << i)) <= 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);
}
niv[1] = 1;
DFS(1);
for (int i = 2; i <= nn; i++)
log[i] = log[i / 2] + 1;
RMQ();
int y;
// for (int i = 1; i <= nn; i++)
// fout << rmq[0][i] << " ";
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;
}