Pagini recente » Borderou de evaluare (job #2471367) | Borderou de evaluare (job #887912) | Cod sursa (job #3363370) | Cod sursa (job #3363451) | Cod sursa (job #3363459)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX = 1e5 + 1, LOG = 17;
int n, m, parent[NMAX], depth[NMAX], up[LOG][NMAX];
vector<int> adj[NMAX];
void precalculare()
{
for(int i = 1; i <= n; i++)
up[0][i] = parent[i];
for(int e = 1; e < LOG; e++)
for(int i = 1; i <= n; i++)
up[e][i] = up[e - 1][up[e - 1][i]];
}
void dfs(int node)
{
depth[node] = depth[parent[node]] + 1;
for(int next : adj[node])
{
if(next == parent[node])
continue;
dfs(next);
}
}
int lca(int u, int v)
{
if(depth[u] > depth[v])
swap(u, v);
for(int e = LOG - 1; e >= 0; e--)
if(depth[v] - (1 << e) >= depth[u])
v = up[e][v];
if(u == v)
return u;
for(int e = LOG - 1; e >= 0; e--)
{
if(up[e][u] != up[e][v])
{
u = up[e][u];
v = up[e][v];
}
}
return parent[u];
}
int main()
{
fin >> n >> m;
for(int i = 2; i <= n; i++)
{
fin >> parent[i];
adj[parent[i]].push_back(i);
adj[i].push_back(parent[i]);
}
dfs(1); precalculare();
while(m--)
{
int u, v; fin >> u >> v;
fout << lca(u, v) << "\n";
}
fin.close();
fout.close();
return 0;
}