Pagini recente » Cod sursa (job #393491) | Cod sursa (job #1581666) | Cod sursa (job #1277584) | Cod sursa (job #704489) | Cod sursa (job #1385874)
#include <fstream>
#include <vector>
using namespace std;
ifstream is ("lca.in");
ofstream os ("lca.out");
const int Nmax = 100001;
int N, Q;
int Euler[Nmax << 1], Depth[Nmax << 1], Ind[Nmax], K;
int RMQ[21][Nmax << 1], Log[Nmax << 1];
vector <int> G[Nmax];
void Read();
void DFS(int node, int lvl);
void RangeMinimumQuery();
int LCA(int x, int y);
int main()
{
Read();
DFS(1, 0);
RangeMinimumQuery();
for (int x, y; Q--; os << LCA(x, y) << '\n')
is >> x >> y;
is.close();
os.close();
}
int LCA(int x, int y)
{
int p1, p2;
p1 = Ind[x], p2 = Ind[y];
if (p1 > p2) swap(p1, p2);
int k = Log[p2 - p1];
return min(Euler[RMQ[k][p1]],
Euler[RMQ[k][p2 - (1 << k) + 1]]);
};
void RangeMinimumQuery()
{
for (int i = 1; i <= K; ++i)
RMQ[0][i] = i;
for (int i = 2; i <= K; ++i)
Log[i] = Log[i >> 1] + 1;
for (int i = 1, k; (1<<i) < K; ++i)
for (int j = 1; j + (1<<i) <= K+1; ++j)
{
k = (1 << (i-1));
if (Depth[RMQ[i-1][j]] <= Depth[RMQ[i-1][j+k]])
RMQ[i][j] = RMQ[i-1][j];
else
RMQ[i][j] = RMQ[i-1][j+k];
}
};
void Read()
{
is >> N >> Q;
for (int i = 2, x; i <= N; ++i)
{
is >> x;
G[x].push_back(i);
}
};
void DFS(int node, int lvl)
{
Ind[node] = ++K;
Euler[K] = node;
Depth[K] = lvl;
for (const int& next : G[node])
{
DFS(next, lvl+1);
Euler[++K] = node;
Depth[K] = lvl;
}
};