Cod sursa(job #3344730)

Utilizator Bianca2507Negret Bianca Bianca2507 Data 5 martie 2026 09:09:18
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");

int n,q;
vector<int>l[100005];
struct numar
{
    int nod,niv;
} rmq[19][200005];
int e[200005],p_curent,p_start[200005];
void dfs(int nod,int niv)
{
    rmq[0][++p_curent]= {nod,niv};
    p_start[nod]=p_curent;
    for(int i=0; i<l[nod].size(); i++)
    {
        int vecin=l[nod][i];
        dfs(vecin,niv+1);
        rmq[0][++p_curent]= {nod,niv};
    }
}
int lca(int x,int y)
{
  int pos_x=p_start[x];
  int pos_y=p_start[y];
  if(pos_x>pos_y)
    swap(pos_x,pos_y);
  int p=e[pos_y-pos_x+1];
  numar st=rmq[p][pos_x];
  numar dr=rmq[p][pos_y-(1<<p)+1];
  if(st.niv<dr.niv)
    return st.nod;
  else
    return dr.nod;
}
int main()
{
    cin>>n>>q;
    for(int i=2; i<=n; i++)
    {
        int x;
        cin>>x;
        l[x].push_back(i);
    }
    p_curent=0;
    dfs(1,1);

    e[1]=0;
    for(int i=2; i<=2*p_curent; i++)
        e[i]=e[i/2]+1;

    for(int p=1; (1<<p)<=p_curent; p++)
        for(int i=1; i<=p_curent; i++)
        {
            numar st=rmq[p-1][i];
            if(i+(1<<(p-1))<=p_curent)
            {
              numar dr=rmq[p-1][i+(1<<(p-1))];
              if(st.niv<dr.niv)
                rmq[p][i]=st;
              else
                rmq[p][i]=dr;
            }
            else
              rmq[p][i]=st;
        }
    while(q--)
    {
        int x,y;
        cin>>x>>y;
        cout<<lca(x,y)<<'\n';
    }
    return 0;
}