Pagini recente » Cod sursa (job #1934786) | Cod sursa (job #225855) | Cod sursa (job #3256490) | Cod sursa (job #643770) | Cod sursa (job #1784870)
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
vector<int> G[100010];
int E[300010],C[100010], F[100010],nr;
int RMQ[21][300010],P[300010];
void eulerian_path(int x,int f,int level)
{
++nr;
RMQ[0][nr] = x;
E[nr] = level;
if (C[x] == 0)
C[x] = nr;
F[x] = nr;
for (int i = 0;i < G[x].size();++i)
{
if (G[x][i] != f)
{
eulerian_path(G[x][i], x, ++level);
++nr;
RMQ[0][nr] = x;
E[nr] = level;
if (C[x] == 0)
C[x] = nr;
F[x] = nr;
}
}
}
void build_RMQ()
{
for (int i = 1;i <= 20;++i)
for (int j = 1;j + (1 << i) <= 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;
P[1] = 0;
for (int i = 2;i <= N;++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,0,0);
build_RMQ();
for (int i = 1;i <= Q;++i)
{
int x, y;
in >> x >> y;
if (C[x] < F[y])
out << query_RMQ(C[x], F[y])<<'\n';
else
out << query_RMQ(C[y], F[x]) << '\n';
}
return 0;
}