Cod sursa(job #3348145)

Utilizator altomMirel Fanel altom Data 19 martie 2026 22:01:32
Problema Lowest Common Ancestor Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.01 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

const int NMAX=1e5+5;
int n, m, cnt, a, b;
vector<int> ad[NMAX];
pair<int, int> e[2*NMAX];
pair<int, int> rmq[32][2*NMAX];
int log[2*NMAX], poz[NMAX];

void dfs(int nod, int tata, int nivel){
    e[++cnt]={nod, nivel};
    poz[nod]=cnt;
    for(auto vecin: ad[nod]){
        if(vecin!=tata){
            dfs(vecin, nod, nivel+1);
            e[++cnt]={nod, nivel};
        }
    }
}

int rmq_query(int st, int dr){
    if(st>dr)
        swap(st, dr);
    int len=dr-st+1;
    int p=log[len];
    pair<int, int> a=rmq[p][st];
    pair<int, int> b=rmq[p][dr-(1<<p)+1];
//    cout<<"wasd: "<<st<<" "<<dr<<" "<<p<<" "<<a.first<<" "<<a.second<<" "<<b.first<<" "<<b.second<<'\n';
    if(a<=b)
        return a.second;
    return b.second;
}

int main()
{
    fin>>n>>m;

    for(int i=2;i<=n;i++){
        fin>>a;
        ad[a].push_back(i);
        ad[i].push_back(a);
    }

    cnt=0;
    dfs(1, 0, 1);

//    for(int i=1;i<=cnt;i++)
//        cout<<e[i].first<<" ";
//    cout<<'\n';

    for(int i=1;i<=cnt;i++){
        rmq[0][i].first=e[i].second;
        rmq[0][i].second=i;
    }

    for(int p=1;(1<<p)<=cnt;p++){
        for(int i=1;i+(1<<p)<cnt;i++){
            rmq[p][i].first=min(rmq[p-1][i].first, rmq[p-1][i+(1<<(p-1))].first);
            if(rmq[p-1][i].first<=rmq[p-1][i+(1<<(p-1))].first){
                rmq[p][i].second=rmq[p-1][i].second;
            }else{
                rmq[p][i].second=rmq[p-1][i+(1<<(p-1))].second;
            }
//            cout<<rmq[p][i].first<<" ";
        }
//        cout<<'\n';
    }

    log[1]=0;
    for(int i=2;i<=cnt;i++){
        log[i]=1+log[i/2];
    }


    while(m--){
        fin>>a>>b;

        a=poz[a], b=poz[b];
//        cout<<a<<" "<<b<<" "<<e[a+1].first<<" "<<e[a+1].second<<" "<<rmq_query(a, b)<<'\n';

        fout<<e[rmq_query(a, b)].first<<'\n';
    }


    return 0;
}