Pagini recente » Cod sursa (job #2631727) | Cod sursa (job #3255489) | Cod sursa (job #2196325) | Cod sursa (job #989909) | Cod sursa (job #3313610)
///LCA
#include <bits/stdc++.h>
using namespace std;
int N,M,t,cnt=0,nivel=1;
vector<int> fii[100005];
vector<pair<int,int>> euler; ///nivelul la care am ajuns prin parcurgerea DFS
unordered_map<int,int> primaAparitie;
pair<int,int> rmq[100005][50]; ///pair de nivel cu nod
int loga[100005];
long long expo[100005]; ///expo[i]= cea mai mare putere de 2 mai mica ca i
size_t sz;
void DFS(int x)
{
if(primaAparitie[x]==0)
{
primaAparitie[x]=cnt;
}
if(fii[x].empty()==1)
{
return;
}
for(size_t i=0;i<fii[x].size();i++)
{
nivel++;
euler.push_back({nivel, fii[x][i]});
cnt++;
DFS(fii[x][i]);
nivel--;
euler.push_back({nivel,x});
cnt++;
}
}
void Logarithm()
{
loga[1]=0;
expo[1]=1;
int l=0;
long long p=2;
for(int i=2;i<=sz;i++)
{
if(i==p)
{
l++;
p*=2;
}
expo[i]=p/2;
loga[i]=l;
}
}
void RMQ()
{
///rmq[i][p]= minimul secventei i...i+2^p-1
for(int i=0;i<sz;i++)
{
rmq[i][0]=euler[i];
}
long long po=1;
for(int p=1;p<=loga[sz];p++)
{
for(int i=0;i<sz;i++)
{
if(rmq[i][p-1].first<=rmq[i+po][p-1].first)
{
rmq[i][p]=rmq[i][p-1];
}
else
{
rmq[i][p]=rmq[i+po][p-1];
}
}
po*=2;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
ifstream cin("lca.in");
ofstream cout("lca.out");
cin>>N>>M;
for(int i=1;i<N;i++)
{
cin>>t;
fii[t].push_back(i+1);
}
euler.push_back({1,1});
DFS(1);
///caut nivelul minim intre 2 prime aparitii ==> LCA
sz=euler.size();
Logarithm();
RMQ();
int n1,n2;
while(M--)
{
cin>>n1>>n2;
int a=primaAparitie[n1], b=primaAparitie[n2];
if(a>b)
{
swap(a,b);
}
//cout<<a<<' '<<b<<'\n';
///rmq de la a la b ?
pair<int,int> p1= rmq[a][loga[b-a+1]];
//cout<<loga[b-a+1]<<' '<<expo[b-a+1]<<' '<<b-expo[b-a+1]+1<<'\n';
pair<int,int> p2= rmq[b-expo[b-a+1]+1][loga[b-a+1]];
//cout<<p1.first<<' '<<p1.second<<' '<<p2.first<<' '<<p2.second<<'\n';
if(p1.first<=p2.first)
{
cout<<p1.second<<'\n';
}
else
{
cout<<p2.second<<'\n';
}
}
return 0;
}