Cod sursa(job #3308706)

Utilizator InformaticianInDevenire1Munteanu Mihnea Gabriel InformaticianInDevenire1 Data 27 august 2025 14:33:18
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.22 kb
#include <bits/stdc++.h>

using namespace std;

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

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

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;
    }
}

int 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]);
        //if (x<10) cout << 0;
        //cout << x << ' ';
    }
    //cout << '\n';
    v.push_back(1e9);
    for (int i=1;i<=N;++i){
        //if (v[i]<10) cout << 0;
        //cout << v[i] << ' ';
        dp[0][i] = min(make_pair(Euler[i],i),make_pair(Euler[i+1],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].first;
            int b = dp[i-1][j+(1<<(i-1))].first;
            if (v[a]<v[b]){
                dp[i][j] = dp[i-1][j];
            }else{
                dp[i][j] = dp[i-1][j+(1<<(i-1))];
            }
            //dp[i][j] = min(dp[i-1][j],dp[i-1][j+(1<<(i-1))]);
        }
    }
    PreCalc_Log(N);
    vector <int> st(N+5,0);
    vector <int> dr(N+5,0);
    for (int i=0;i<N;++i){
        int x = Euler[i];
        if (st[x]==0){
            st[x] = i+1;
        }
        dr[x] = i+1;
    }
    //cout << '\n';
    for (int i=1;i<=m;++i){
        int L,R;
        fin >> L >> R;
        L = st[L];
        R = dr[R];
        //cout << L << ' ' << R << '\n';
        if (L==R){
            fout << v[L] << '\n'; // caz particular
            continue;
        }
        int p = lg[R-L];
        pair <int,int> ans = min(dp[p][L],dp[p][R-(1<<p)]);
        fout << ans.first << '\n';
    }
    return 0;
}