Pagini recente » Cod sursa (job #311210) | Cod sursa (job #795086) | Cod sursa (job #936823) | Cod sursa (job #1606510) | Cod sursa (job #3164685)
// 381ms
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX = 1e5 + 5, LOG = 25;
int n, m;
int N; // N = 2 * n - 1 - lungimea turului Euler
int E[2 * NMAX]; // nodurile parcurse in turul Euler
int niv[2 * NMAX]; // niv[i] = nivelul in arbore al nodului E[i]
int poz[2 * NMAX]; // poz[x] = poz primei aparitii a lui x in turul Euler
int rmq[LOG][2 * NMAX]; // rmq[i][j] = pozitia in sirul E a nodului cu nivel minim in intervalul [j, j + 2^i]
vector<int> G[NMAX];
void CitesteArbore();
inline void DFS(int x, int h);
inline void RMQ();
inline int LCA(int x, int y);
int main()
{
CitesteArbore();
DFS(1, 0);
RMQ();
int x, y;
while (m--)
{
fin >> x >> y;
fout << LCA(x, y) << '\n';
}
}
inline int LCA(int x, int y)
{
int px = poz[x];
int py = poz[y];
if (px > py)
swap(px, py);
int k = log2(py - px + 1);
if (niv[rmq[k][px]] < niv[rmq[k][py - (1 << k) + 1]])
return E[rmq[k][px]];
return E[rmq[k][py - (1 << k) + 1]];
}
inline void DFS(int x, int nv)
{
E[++N] = x;
niv[N] = nv;
poz[x] = N;
for(int y : G[x])
{
DFS(y, nv + 1);
E[++N] = x;
niv[N] = nv;
}
}
inline void RMQ()
{
for (int i = 1; i <= N; ++i)
rmq[0][i] = i;
int p1, p2;
for (int i = 1; (1 << i) <= N; ++i)
for (int j = 1; j <= N; ++j)
{
p1 = rmq[i - 1][j];
p2 = rmq[i - 1][j + (1 << (i - 1))];
if (niv[p1] < niv[p2])
rmq[i][j] = p1;
else
rmq[i][j] = p2;
}
}
void CitesteArbore()
{
fin >> n >> m;
for(int i = 2, tata; i <= n; ++i)
{
fin >> tata;
G[tata].push_back(i);
}
}