Pagini recente » Cod sursa (job #336187) | Cod sursa (job #1090833) | Cod sursa (job #2159245) | Cod sursa (job #3238462) | Cod sursa (job #2812241)
#include <bits/stdc++.h>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
#define cin f
#define cout g
const int Max = 1e5;
int n,m;
vector< int > v[Max];
void read()
{
f>>n>>m;
int i;
for(i=2;i<=n;i++)
{
int parent;
f>>parent;
v[parent].push_back(i);
}
}
struct Node{
int nod;
int depth;
};
vector < Node > parcurgere;
int lastaparitii[Max];
int firstaparitii[Max];
void dfsEuler(int nod,int depth)
{
firstaparitii[nod] = parcurgere.size();
parcurgere.push_back({nod,depth});
for(auto child : v[nod])
{
dfsEuler(child,depth + 1);
parcurgere.push_back({nod,depth});
}
lastaparitii[nod] = parcurgere.size() - 1;
}
//https://www.infoarena.ro/problema/lca
const int Lmax = 2 * Max;
Node ST[Lmax][21];
Node merge(Node n1, Node n2)
{
if(n1.depth < n2.depth)
return n1;
return n2;
}
void init(vector < Node > v)
{
int i,j;
int n = v.size() - 1;
for(i=0;i<n;i++)
ST[i][0] = v[i];
for(j = 1; (1<<j) <= n;j++)
{
for(i = 0;i + (1<<j) <= n;i++)
ST[i][j] = merge(ST[i][j - 1],ST[i + (1<<(j - 1))][j - 1]);
}
}
int get_lca(int n1,int n2)
{
//n1 apare inainte de n2 l <= r//
int left = min(firstaparitii[n1],firstaparitii[n2]);
int right = max(lastaparitii[n1],lastaparitii[n2]);
int k = log2(right - left + 1);
Node ans = merge(ST[left][k],ST[right - (1<<k) + 1][k]);
return ans.nod;
}
void precompute()
{
dfsEuler(1,1);//etapa 1
//rmq pe parcurgere
init(parcurgere);
}
void query()
{
while(m --)
{
int n1,n2;
f>>n1>>n2;
cout<<get_lca(n1,n2)<<'\n';
}
}
int main()
{
read();
precompute();
query();
return 0;
}