Cod sursa(job #2963387)

Utilizator razvanalexrotaruRazvan Alexandru Rotaru razvanalexrotaru Data 10 ianuarie 2023 23:41:27
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.34 kb
#include <bits/stdc++.h>
#include <fstream>
#define cin fin
#define cout fout
using namespace std;
ifstream cin ("lca.in");
ofstream cout ("lca.out");
vector<int>G[200008];
int euler[200008],Rmq[64][200008],i,cnt,logg[200008],n,m,x,y,H[200008],poz[200008],viz[200008];
void dfs(int nod,int nivel)
{
    viz[nod]=1;
    euler[++cnt]=nod;
    H[nod]=nivel;
    poz[nod]=cnt;
    for(auto i:G[nod])
    if(viz[i]==0)
    {
        dfs(i,nivel+1);
        H[++cnt]=nivel;
        euler[cnt]=nod;
    }

}
void rmq()
{
    int i,j;
    for(i=2;i<=cnt;++i)
        logg[i]=logg[i>>1]+1;
    for(i=1;i<=cnt;++i)
		Rmq[0][i]=euler[i];

	for(i=1;(1<<i)<cnt;++i)
		for(j=1;j<=cnt-(1<<i);++j)
		{
			int l=(1<<(i-1));
			Rmq[i][j]=Rmq[i-1][j];
			if(H[Rmq[i-1][j+l]]<H[Rmq[i][j]])
				Rmq[i][j]=Rmq[i-1][j+l];
		}
}
int lca(int st, int dr)
{
    int val1=poz[st],val2=poz[dr];
    if(val1>val2)
        swap(val1,val2);
    int diff=val2-val1+1;
    int l=logg[diff];
    int sol=Rmq[l][val1];
    if(H[sol]>H[Rmq[l][val2-(1>>l)+1]])
        sol=Rmq[l][val2-(1<<l)+1];
    return sol;
}
int main()
{
    cin>>n>>m;
    for(i=2;i<=n;i++)
    {
        cin>>x;
        G[x].push_back(i);
    }
    dfs(1,0);
    rmq();
    for(i=1;i<=m;i++)
    {
        cin>>x>>y;
        cout<<lca(x,y)<<'\n';
    }
    return 0;
}