Pagini recente » Cod sursa (job #1384784) | Cod sursa (job #1093209) | Monitorul de evaluare | Cod sursa (job #2530380) | Cod sursa (job #3346088)
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int n, m, timer,l;
vector<vector<int>> adj,up;
vector<int>tin, tout;
void dfs(int v, int p)
{
tin[v] = ++timer;
up[v][0] = p;
for (int i = 1; i <= l; ++i)
up[v][i] = up[up[v][i - 1]][i - 1];
for (int u : adj[v])
if (u != p)
dfs(u, v);
tout[v] = ++timer;
}
bool is_ancestor(int u, int v)
{
return tin[u] <= tin[v] && tout[u] >= tout[v];
}
int lca(int u, int v)
{
if (is_ancestor(u, v))
return u;
if (is_ancestor(v, u))
return v;
for (int i = l; i >= 0; --i)
if (!is_ancestor(up[u][i], v))
u = up[u][i];
return up[u][0];
}
void preprocess()
{
timer = 0;
dfs(1, 1);
}
int main()
{
in >> n >> m;
l = ceil(log2(n));
adj.resize(n + 1);
tin.resize(n + 1);
tout.resize(n + 1);
up.assign(n + 1, vector<int>(l + 1));
for (int i = 2; i <= n; ++i)
{
int a;
in >> a;
adj[a].push_back(i);
adj[i].push_back(a);
}
preprocess();
for (int i = 0; i < m; ++i)
{
int a, b;
in >> a >> b;
out << lca(a, b) << "\n";
}
return 0;
}