Pagini recente » Cod sursa (job #2273556) | Cod sursa (job #1876564) | Cod sursa (job #658664) | Cod sursa (job #2014754) | Cod sursa (job #1784914)
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
vector<int> G[100010];
int T[300010],E[300010],C[100010],nr;
int RMQ[23][300010],P[300010];
void eulerian_path(int x,int level)
{
T[++nr] = x;
E[nr] = level;
if (C[x] == 0)
C[x] = nr;
for (int i = 0;i < G[x].size();++i)
{
eulerian_path(G[x][i], level+1);
T[++nr] = x;
E[nr] = level;
}
}
void build_RMQ()
{
for (int i = 1;i <= 22;++i)
for (int j = 1;(j + (1 << i) -1) <= nr;++j)
if (E[RMQ[i - 1][j]] < E[RMQ[i - 1][j + (1 << (i - 1))]])
RMQ[i][j] = RMQ[i - 1][j];
else
RMQ[i][j] = RMQ[i - 1][j + (1 << (i - 1))];
}
int query_RMQ(int a, int b)
{
int put = P[b - a+1];
if (E[RMQ[put][a]] < E[RMQ[put][b - (1 << put) +1]])
return RMQ[put][a];
else
return RMQ[put][b - (1 << put) + 1];
}
int main()
{
int N,Q;
in >> N >> Q;
for (int i = 2;i <= 300000;++i)
P[i] = P[i / 2] + 1;
for (int i = 2;i <= N;++i)
{
int e;
in >> e;
G[e].push_back(i);
}
eulerian_path(1,1);
for (int i = 1;i <= nr;++i)
RMQ[0][i] = i;
build_RMQ();
for (int i = 1;i <= Q;++i)
{
int x, y;
in >> x >> y;
if (C[x] < C[y])
out << T[query_RMQ(C[x], C[y])]<<'\n';
else if (C[x]>C[y])
out << T[query_RMQ(C[y], C[x])] << '\n';
else
out << x << '\n';
}
return 0;
}