Cod sursa(job #3308807)

Utilizator InformaticianInDevenire1Munteanu Mihnea Gabriel InformaticianInDevenire1 Data 28 august 2025 13:33:38
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 kb
#include <bits/stdc++.h>
#define int long long

using namespace std;

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

int tata[200005];
int lvl[200005];
vector <int> gr[200005];
vector <int> Euler;
vector <int> v;
int viz[200005];
pair <int,int> dp[22][200005];
int lg[200005];

void DFS(int I){
    Euler.push_back(I);
    viz[I] = 1;
    for (auto son:gr[I]){
        if (viz[son]) continue;
        DFS(son);
        Euler.push_back(I);
    }
}

void PreCalc_Log(int n){
    lg[1] = 0;
    for (int i=2;i<=n;++i){
        lg[i] = lg[i/2]+1;
    }
}

signed main()
{
    int n,m;
    fin >> n >> m;
    lvl[1] = 1;
    tata[1] = 1;
    for (int i=2;i<=n;++i){
        fin >> tata[i];
        lvl[i] = lvl[tata[i]]+1;
        gr[tata[i]].push_back(i);
    }
    DFS(1);
    int N = Euler.size();
    v.push_back(0);
    for (auto x:Euler){
        v.push_back(lvl[x]);
    }
    v.push_back(1e9);
    Euler.push_back(1e9);
    for (int i=1;i<=N;++i){
        dp[0][i] = min(make_pair(v[i],Euler[i]),make_pair(v[i+1],Euler[i+1]));
    }
    for (int i=1;i<20;++i){
        for (int j=1;j<=N;++j){
            if (j+(1<<i)>N) continue;
            int a = dp[i-1][j].second;
            int b = dp[i-1][j+(1<<(i-1))].second;
            if (a<b){
                dp[i][j] = dp[i-1][j];
            }else{
                dp[i][j] = dp[i-1][j+(1<<(i-1))];
            }
        }
    }
    PreCalc_Log(N);
    vector <int> st(N+5,0);
    for (int i=0;i<N;++i){
        int x = Euler[i];
        if (st[x]==0){
            st[x] = i+1;
        }
    }
    for (int i=1;i<=m;++i){
        int L,R;
        fin >> L >> R;
        L = st[L];
        R = st[R];
        if (L>R) swap(L,R);
        if (L==R){
            fout << Euler[L] << '\n'; // caz particular
            continue;
        }
        int p = lg[R-L];
        //pair <int,int> ans = min(dp[p][L],dp[p][R-(1<<p)]);
        pair <int,int> ans;
        if (dp[p][L].second<dp[p][R-(1<<p)].second) ans = dp[p][L];
        else ans = dp[p][R-(1<<p)];
        fout << ans.second << '\n';
    }
    return 0;
}