Cod sursa(job #3327205)

Utilizator mariusharabariMarius Harabari mariusharabari Data 2 decembrie 2025 19:43:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.89 kb
#include <bits/stdc++.h>
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

const int NMAX=1e5+1, EMAX=20;
int n, m;
vector <int> g[NMAX], lin;
int lvl[NMAX], s[NMAX], f[NMAX], rmq[EMAX][3*NMAX];

void dfs(int nod, int h){
    lvl[nod]=h;
    lin.push_back(nod);

    rmq[0][lin.size()-1]=nod;
    //cout<<lvl[rmq[0][lin.size()-1]]<<' ';
    s[nod]=lin.size()-1;
    for(int vec : g[nod]){
        dfs(vec, h+1);
        lin.push_back(nod);
        rmq[0][lin.size()-1]=nod;
        //cout<<lvl[rmq[0][lin.size()-1]]<<' ';
    }
    f[nod]=lin.size()-1;
}

bool comp(int x, int y){
    return lvl[x]<lvl[y];
}

int main(){
    fin>>n>>m;
    for(int i=2;i<=n;i++){
        int p;
        fin>>p;
        g[p].push_back(i);
    }
    lin.push_back(0);
    dfs(1, 1);
    /*cout<<endl;
    for(int i=1;i<=n;i++){
        cout<<i<<' '<<lvl[i]<<' '<<s[i]<<' '<<f[i]<<endl;
    }*/

    int len=lin.size(), lg[len];
    lg[1]=0;
    //cout<<len<<endl;

    for(int i=2;i<len;i++)
        lg[i]=lg[i/2]+1;

    for(int e=1;e<=lg[len-1];e++){
        //cout<<e<<endl;
        for(int i=1;i<=len-(1<<e);i++){
            if(comp(rmq[e-1][i], rmq[e-1][i+(1<<(e-1))]))
                rmq[e][i]=rmq[e-1][i];
            else
                rmq[e][i]=rmq[e-1][i+(1<<(e-1))];
            //cout<<i<<' '<<rmq[e][i]<<' '<<lvl[rmq[e][i]]<<endl;
        }
    }

    while(m--){
        int st, fi;
        fin>>st>>fi;
        //cout<<st<<' '<<fi<<endl;

        st=s[st];
        fi=s[fi];
        if(st>fi){
            swap(st,fi);
        }
        //cout<<st<<' '<<fi<<endl;
        int e=lg[fi-st+1], ans;
        //cout<<e<<endl;
        if(comp(rmq[e][st], rmq[e][fi-(1<<e)+1]))
            ans=rmq[e][st];
        else
            ans=rmq[e][fi-(1<<e)+1];
        //cout<<ans<<endl;
        fout<<ans<<'\n';
    }

    return 0;
}