Pagini recente » Cod sursa (job #1543830) | Cod sursa (job #2805034) | Cod sursa (job #3189801) | Cod sursa (job #1647107) | Cod sursa (job #1960441)
#include <bits/stdc++.h>
using namespace std;
const int SIZE = 100000, MAXN = 100001;
#define fastcall __attribute__((optimize("-O3")))
#define inline __inline__ __attribute__((always_inline))
struct InParsare
{
char buffer[SIZE];
int index;
inline fastcall char next_char()
{
if(index == SIZE)
{
fread(buffer,1,SIZE,stdin);
index = 0;
return next_char();
}
return buffer[index++];
}
InParsare()
{
freopen("lca.in","r",stdin);
index = 0;
fread(buffer,1,SIZE,stdin);
}
inline fastcall InParsare& operator >> (int &x)
{
x = 0;
char c;
for(c = next_char(); c < '0' || c > '9'; c = next_char());
for(;c >= '0' && c <= '9'; c = next_char())
x = x * 10 + c - '0';
return *this;
}
}in;
int n, m, tata[MAXN], copil[MAXN];
vector<pair<int, int> >euler;
vector<int> tree[MAXN];
bool viz[MAXN];
int dp[20][MAXN];
int pozitie[MAXN];
inline fastcall void citire()
{
in>>n>>m;
tata[1] = 1;
for(int i = 2; i <= n; i++)
{
in>>tata[i];
tree[i].push_back(tata[i]);
tree[tata[i]].push_back(i);
}
}
fastcall void dfs(int nod,int niv)
{
viz[nod] = 1;
if(!pozitie[nod])
pozitie[nod] = euler.size();
euler.push_back({nod, niv+1});
for(int it : tree[nod])
{
if(!viz[it])
{
dfs(it, niv+1);
euler.push_back({nod, niv+1});
}
}
}
inline fastcall void build_rmq()
{
int n = euler.size() - 1;
for(int i=1;i<=n;i++)
dp[0][i] = euler[i].first;
for(int i=1;(1<<i) <= n; i++)
{
for(int j=1;j<=n-(1<<i)+1;j++)
{
int power = 1<<(i-1);
dp[i][j] = min(dp[i-1][j],dp[i-1][j+power]);
}
}
}
inline fastcall int query(int inc, int sf)
{
int x = pozitie[inc], y = pozitie[sf];
if(x > y)
swap(x,y);
return min(dp[((int)log2(y-x+1))][x],dp[((int)log2(y-x+1))][x+((y-x+1) - (1<<((int)log2(y-x+1))))]);
}
int main()
{
citire();
euler.push_back({0,0});
dfs(1, 0);
build_rmq();
freopen("lca.out","w",stdout);
while(m--)
{
int a, b;
in>>a>>b;
printf("%d\n",query(a,b));
}
return 0;
}