Pagini recente » Cod sursa (job #901891) | Cod sursa (job #312326) | Monitorul de evaluare | Cod sursa (job #60324) | Cod sursa (job #1414488)
#include <bits/stdc++.h>
using namespace std;
const int Nmax = 100000 + 1;
vector<int> G[Nmax];
int tata[Nmax];
int depth[Nmax];
int size[Nmax];
int path[Nmax];
int pos_in_path[Nmax];
int length_path[Nmax];
int start_node[Nmax];
int N, Q;
int nrPaths;
void dfs(int nod)
{
int hson = 0;
size[nod] = 1;
for (auto& son: G[nod])
{
if (tata[son] == 0)
{
tata[son] = nod;
depth[son] = depth[nod] + 1;
dfs(son);
size[nod] += size[son];
if (size[hson] < size[son])
hson = son;
}
}
if (hson == 0)
path[nod] = nrPaths++;
else
path[nod] = path[hson];
pos_in_path[nod] = length_path[ path[nod] ]++;
}
void build_hpd()
{
tata[1] = 1;
depth[1] = 0;
dfs(1);
for (int i = 1; i <= N; ++i)
{
pos_in_path[i] = length_path[ path[i] ] - pos_in_path[i] - 1;
if (pos_in_path[i] == 0)
start_node[ path[i] ] = i;
}
}
int lca(int x, int y)
{
while (path[x] != path[y])
{
if (depth[ start_node[ path[x] ] ] > depth[ start_node[ path[y] ] ])
x = tata[ start_node[ path[x] ] ];
else
y = tata[ start_node[ path[y] ] ];
}
return pos_in_path[x] < pos_in_path[y] ? x : y;
}
int main()
{
ifstream in("lca.in");
ofstream out("lca.out");
in >> N >> Q;
for ( int i = 2, a; i <= N; ++i )
{
in >> a;
G[a].push_back( i );
}
build_hpd();
for (int i = 1; i <= Q; ++i)
{
int a, b;
in >> a >> b;
out << lca(a, b) << "\n";
}
return 0;
}