Pagini recente » Cod sursa (job #3256576) | Cod sursa (job #2775183) | Cod sursa (job #286631) | Cod sursa (job #387914) | Cod sursa (job #1385884)
#include <fstream>
#include <vector>
using namespace std;
ifstream is ("lca.in");
ofstream os ("lca.out");
const int BUFFER = 1<<17;
char Pars[BUFFER], *p;
inline int GET();
inline void Check();
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();
inline void DFS(int node, int lvl);
void RangeMinimumQuery();
inline int LCA(int x, int y);
int main()
{
Read();
DFS(1, 0);
RangeMinimumQuery();
for (int x, y; Q--; os << LCA(x, y) << '\n')
x = GET(), y = GET();
is.close();
os.close();
}
inline 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()
{
p = Pars;
N = GET();
Q = GET();
for (int i = 2, x; i <= N; ++i)
{
x = GET();
G[x].push_back(i);
}
};
inline int GET()
{
while (*p < '0' || *p > '9') ++p, Check();
int X = 0;
while ('0' <= *p && *p <= '9') X = X*10 + (*p - '0'), ++p, Check();
return X;
};
inline void Check()
{
if (*p == '\0') is.get(Pars, BUFFER, '\0'), p = Pars;
};
inline 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;
}
};