Pagini recente » Cod sursa (job #649455) | Cod sursa (job #1093152) | Cod sursa (job #1558435) | Cod sursa (job #1107196) | Cod sursa (job #2738527)
#include <fstream>
#include <vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n, m;
int depth[100001];
int pos[100001];
int euler[200001], nrEuler;
int log2[200001];
int rmq[200001][18];
vector < int > adj[100001];
void dfs(int node, int d)
{
depth[node] = d;
euler[++nrEuler] = node;
pos[node] = nrEuler;
for (auto it : adj[node])
{
dfs(it, d + 1);
euler[++nrEuler] = node;
pos[node] = nrEuler;
}
}
int lca(int x, int y)
{
if (x == y)
return x;
x = pos[x];
y = pos[y];
if (x > y)
swap(x, y);
int k = log2[y - x + 1];
if (depth[rmq[x][k]] < depth[rmq[y - (1 << k) + 1][k]])
return rmq[x][k];
else
return rmq[y - (1 << k) + 1][k];
}
int main()
{
f >> n >> m;
for (int node = 2; node <= n; node++)
{
int parent; f >> parent;
adj[parent].push_back(node);
}
dfs(1, 0);
for (int i = 2; i <= nrEuler; i++)
log2[i] = log2[i / 2] + 1;
for (int i = 1; i <= nrEuler; i++)
rmq[i][0] = euler[i];
for (int i = 1; (1 << i) <= nrEuler; i++)
for (int j = 1; j + (1 << i) - 1 <= nrEuler; j++)
if (depth[rmq[j][i - 1]] < depth[rmq[j + (1 << (i - 1))][i - 1]])
rmq[j][i] = rmq[j][i - 1];
else
rmq[j][i] = rmq[j + (1 << (i - 1))][i - 1];
while (m--)
{
int x, y; f >> x >> y;
g << lca(x, y) << "\n";
}
return 0;
}