Pagini recente » Cod sursa (job #1533963) | Cod sursa (job #1063442) | Cod sursa (job #750442) | Istoria paginii runda/cex02/clasament | Cod sursa (job #3122321)
#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 readInt(int &x)
{
char c;
while(1)
{
c = getchar();
if(c < '0' || c > '9')
continue;
x = c - '0';
break;
}
while(1)
{
c = getchar();
if(c == EOF)
break;
if(c < '0' || c > '9')
break;
if(c >= '0' && c <= '9')
x = x * 10 + c - '0';
}
}
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
readInt(n);
readInt(q);
for(int i = 2; i <= n; ++i)
{
int a;
readInt(a);
v[a].push_back(i);
}
levels = log2(n);
dfs(1);
for(int i = 1; i <= q; ++i)
{
int a, b;
readInt(a), readInt(b);
std::cout << lca(a, b) << '\n';
}
}