Pagini recente » Cod sursa (job #1403683) | Cod sursa (job #3275714) | Cod sursa (job #1032277) | Cod sursa (job #1699747) | Cod sursa (job #3257607)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
int const lmax=100007;
int const mmax=lmax*30;///nu merge pentru algoritmi unde memoria e mare
int euler[mmax],ind,n,q;
vector<int> G[lmax];
int rmq[27][mmax][2],lg2[mmax];
int level[lmax],firstap[lmax];
bool viz[lmax];///folosit pentru firstap
void precalc()
{
for(int j=0;j<ind;j++)
{
rmq[0][j][0]=level[euler[j]];
rmq[0][j][1]=euler[j];
}
for(int i=1;1<<i <= ind ; i++)
{
for(int j=0;j+(1<<i)-1<ind;j++)
{
//rmq[i][j]=min(rmq[i-1][j],rmq[i-1][j+(1<<(i-1))]);
if(rmq[i-1][j][0]<=rmq[i-1][j+(1<<(i-1))][0])
{
rmq[i][j][0]=rmq[i-1][j][0];
rmq[i][j][1]=rmq[i-1][j][1];
}
else
{
rmq[i][j][0]=rmq[i-1][j+(1<<(i-1))][0];
rmq[i][j][1]=rmq[i-1][j+(1<<(i-1))][1];
}
}
}
}
void dfs(int node, int dad)
{
euler[ind++]=node;
level[node]=level[dad]+1;
for(auto vec:G[node])
{
if(vec==dad)continue;
dfs(vec,node);
euler[ind++]=node;
}
}
int querry(int a, int b)
{
a=firstap[a];
b=firstap[b];
if(a>b)
{
swap(a,b);///a va fi mereu "st" si b "dr"
}
int len=b-a+1;
int loglen=lg2[len];
return min(rmq[loglen][a][1],rmq[loglen][b+1-(1<<loglen)][1]);///trebuie sa fac legatura intre minim si nodul care ii apartine
}
int main()
{
fin>>n>>q;
for(int i=2;i<n+1;i++)
{
int a;
fin>>a;
G[a].push_back(i);
G[i].push_back(a);
}
level[1]=1;
dfs(1,0);
for(int i=2;i<=ind;i++)
{
lg2[i]=lg2[i>>1]+1;
}
for(int i=0;i<ind;i++)
{
if(viz[euler[i]]==false)
{
viz[euler[i]]=true;
firstap[euler[i]]=i;
}
}
precalc();
for(int i=0;i<q;i++)
{
int a, b;
fin>>a>>b;
fout<<querry(a,b)<<"\n";
}
fin.close();
fout.close();
return 0;
}