Pagini recente » Borderou de evaluare (job #1856316) | Cod sursa (job #815015) | Cod sursa (job #447826) | Cod sursa (job #568650) | Cod sursa (job #2573461)
#include <bits/stdc++.h>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
vector<int>graph[100005];
int n, nr_q,x, euler[200005], inaltime=0, valput, a, b;
int sp[200005][20], ind_euler=1, first[100005], height[200005];
void create_euler(int ind)
{
if (!first[ind])
first[ind]=ind_euler;
euler[ind_euler]=ind;
height[ind_euler++]=inaltime;
for (auto &v:graph[ind])
{
inaltime++;
create_euler(v);
inaltime--;
euler[ind_euler]=ind;
height[ind_euler++]=inaltime;
}
}
void create_sp()
{
for (int i=1; i<ind_euler; ++i)
sp[i][0]=i;
for (int putere=1; (1<<putere)<=ind_euler; ++putere)
{
valput=(1<<putere);
for (int i=1; i+valput<ind_euler; ++i)
{
if (height[sp[i][putere-1]]<height[sp[i+(valput>>1)][putere-1]])
sp[i][putere]=sp[i][putere-1];
else
sp[i][putere]=sp[i+(valput>>1)][putere-1];
}
}
}
int query(int st, int dr)
{
if (st>dr)
swap(st,dr);
int dif=dr-st+1;
int vallog=log2(dif);
int vst=sp[st][vallog];
int vdr=sp[dr-(1<<vallog)+1][vallog];
if (height[vst]<height[vdr])
return euler[vst];
return euler[vdr];
}
int main()
{
f >> n >> nr_q;
for (int i=2; i<=n; ++i)
{
f >> x;
graph[x].push_back(i);
}
create_euler(1);
create_sp();
for(int i=1; i<=nr_q; ++i)
{
f >> a >> b;
g << query(first[a],first[b]) << '\n';
}
return 0;
}