Pagini recente » Cod sursa (job #836168) | Cod sursa (job #971045) | Cod sursa (job #12982) | Cod sursa (job #529069) | Cod sursa (job #1932489)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
ifstream fi("lca.in");
ofstream fo("lca.out");
int dp[17][100001], T[100001], L[100001], N, Q, x, y, result, hmax;
vector<int> muchii[100001];
void bfs(int start);
int lca(int node1, int node2);
void read();
void solve();
int main()
{
read();
solve();
return 0;
}
void read()
{
fi >> N >> Q;
T[1] = -1;
dp[0][1] = -1;
for (int i = 2;i <= N;i++)
{
fi >> T[i];
muchii[T[i]].push_back(i);
dp[0][i] = T[i];
}
}
void solve()
{
bfs(1);
for(int i=1;(1<<i)<=hmax;i++)
for (int j = 1;j <= N;j++)
dp[i][j] = dp[i - 1][dp[i - 1][j]];
for (int i = 1;i <= Q;i++)
{
fi >> x >> y;
result = lca(x, y);
fo << result << '\n';
}
}
void bfs(int start)
{
queue<int> q;
q.push(start);
L[start] = 0;
bool viz[100001];
memset(viz, false, sizeof(viz));
viz[start] = true;
while (!q.empty())
{
int node = q.front();
q.pop();
for (int i = 0;i < muchii[node].size();i++)
{
int node2 = muchii[node][i];
if (!viz[node2])
{
L[node2] = L[node] + 1;
viz[node2] = true;
q.push(node2);
if (L[node2] > hmax)
hmax = L[node2];
}
}
}
return;
}
int lca(int node1, int node2)
{
int p;
if (L[node1] < L[node2])
p = node1, node1 = node2, node2 = p;
int log;
for (log = 1;(1 << log) <= L[node1];log++);
log--;
for (int i = log;i >= 0;i--)
if (L[node1] - (1 << i) >= L[node2])
node1 = dp[i][node1];
if (node1 == node2)
return node1;
for (int i = log; i >= 0;i--)
if (dp[i][node1]!=-1 && dp[i][node1] != dp[i][node2])
node1 = dp[i][node1], node2 = dp[i][node2];
return T[node1];
}