Pagini recente » Cod sursa (job #360049) | Profil Boscheti | Cod sursa (job #1291687) | Istoria paginii utilizator/oanadagreat | Cod sursa (job #3122318)
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#define MAX 100000
#define FILES freopen("lca.in","r",stdin);\
freopen("lca.out","w",stdout);
using namespace std;
vector<int> v[MAX + 5];
int n, q, up[MAX + 5][17], Time, levels;
int nodeIn[MAX + 5], nodeOut[MAX + 5];
void dfs(int x)
{
nodeIn[x] = ++Time;
for(int i = 1; i <= levels; ++i)
up[x][i] = up[up[x][i - 1]][i - 1];
for(auto i : v[x])
{
if(!nodeIn[i])
{
up[i][0] = x;
dfs(i);
}
}
nodeOut[x] = ++Time;
}
bool isAncestor(int a, int b)
{
return nodeIn[b] >= nodeIn[a] && nodeOut[b] <= nodeOut[a];
}
int lca(int a,int b)
{
if(isAncestor(a, b))
return a;
if(isAncestor(a, b))
return b;
int exp = levels;
while(exp >= 0)
{
while(exp >= 0 && !up[a][exp])
exp--;
while(exp >= 0 && isAncestor(up[a][exp], b))
exp--;
if(exp >= 0)
a = up[a][exp];
}
return up[a][0];
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
FILES
std::cin >> n >> q;
for(int i = 2; i <= n; ++i)
{
int a;
std::cin >> a;
v[a].push_back(i);
}
levels = log2(n);
dfs(1);
for(int i = 1; i <= q; ++i)
{
int a, b;
std::cin >> a >> b;
std::cout << lca(a, b) << '\n';
}
}