Pagini recente » Borderou de evaluare (job #2017168) | Cod sursa (job #2345492) | Cod sursa (job #913365) | Borderou de evaluare (job #2022350) | Cod sursa (job #3131210)
#include <bits/stdc++.h>
using namespace std;
ifstream in ("lca.in");
ofstream out ("lca.out");
const int NMAX = 1e5;
const int p2[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144};
int p[NMAX + 5];
int depth[NMAX + 5];
int rmq[18][NMAX + NMAX + 5];
int lg2[NMAX + NMAX + 5];
int tin[NMAX + 5];
vector<int>g[NMAX + 5];
int t = 0;
void dfs (int u)
{
depth[u] = depth[p[u]] + 1;
tin[u] = ++t;
rmq[0][t] = u;
for (const auto &v : g[u])
{
dfs(v);
rmq[0][++t] = u;
}
}
#define compare(a,b) (depth[a] < depth[b]? a : b)
int lca (int u, int v)
{
u = tin[u], v = tin[v];
if (u > v) swap(u, v);
int k = lg2[v - u + 1];
return compare(rmq[k][u], rmq[k][v - p2[k] + 1]);
}
int main()
{
int n, q;
in >> n >> q;
for (int i=2; i<=n; i++)
{
in >> p[i];
g[p[i]].push_back(i);
}
dfs(1);
int m = (n << 1);
for (int i=2; i<m; i++)
lg2[i] = lg2[i >> 1] + 1;
for (int j=1; p2[j] < m; j++)
{
for (int i=1; i+p2[j]-1<m; i++)
{
rmq[j][i] = compare(rmq[j-1][i], rmq[j-1][i+p2[j-1]]);
}
}
while (q--)
{
int u, v;
in >> u >> v;
out << lca(u, v) << '\n';
}
return 0;
}