Pagini recente » Cod sursa (job #814231) | Cod sursa (job #1278847) | Cod sursa (job #2688959) | Cod sursa (job #773716) | Cod sursa (job #2341326)
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n, m, query_left, query_right, kid, euler[200010], height[200010], ind=1, lvl;
int first[100005], sp[200005][20], val_log;
vector<int>kids[100005];
void create_euler(int node)
{
if (first[node]==0)
{
first[node]=ind;
}
euler[ind]=node;
height[ind++]=lvl;
if (kids[node].empty())
{
return;
}
for (auto &v:kids[node])
{
lvl++;
create_euler(v);
lvl--;
euler[ind]=node;
height[ind++]=lvl;
}
}
void create_sp()
{
int size_rmq=2*n-1;
val_log=(int)log2(size_rmq);
for (int i=1; i<=size_rmq; i++)
{
sp[i][0]=i;
}
for (int j=1; j<=val_log; j++)
{
int val_dif=1<<j;
for (int i=1; i<=size_rmq-val_dif+1; i++)
{
if (height[sp[i][j-1]]<height[sp[i+(1<<(j-1))][j-1]])
sp[i][j]=sp[i][j-1];
else
sp[i][j]=sp[i+(1<<(j-1))][j-1];
}
}
/* for (int i=1; i<=size_rmq; i++)
{
for (int j=0; j<=val_log; j++)
{
cout << sp[i][j] <<' ';
}
cout << '\n';
}*/
}
int find_min(int left, int right)
{
int val_left=first[left];
int val_right=first[right];
int dif=val_right-val_left+1;
int val_log=(int)log2(dif);
if (val_right<val_left)
swap(val_left,val_right);
int val_rmq_1=sp[val_left][val_log];
int val_rmq_2=sp[val_right-(1<<(val_log))][val_log];
if (height[val_rmq_1]<height[val_rmq_2])
{
return euler[val_rmq_1];
}
return euler[val_rmq_2];
}
int main() {
f >> n >> m;
for (int i=2; i<=n; i++)
{
f >> kid;
kids[kid].push_back(i);
}
create_euler(1);
create_sp();
for (int query=0; query<m; ++query)
{
f >> query_left >> query_right;
g << find_min(query_left,query_right) << '\n';
}
return 0;
}