Cod sursa(job #3309037)

Utilizator InformaticianInDevenire1Munteanu Mihnea Gabriel InformaticianInDevenire1 Data 31 august 2025 12:51:31
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.01 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 <pair <int,int>> v;
int viz[200005];
pair <int,int> aint[4*500005]; // level,node

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 Build(int node,int L,int R){
    if (L==R){
        aint[node] = v[L];
        return;
    }
    int M = (L+R)/2;
    Build(2*node,L,M);
    Build(2*node+1,M+1,R);
    aint[node] = min(aint[2*node],aint[2*node+1]);
}

pair <int,int> Query(int node,int L,int R,int a,int b){
    if (a<=L and R<=b) return aint[node];
    int M = (L+R)/2;
    pair <int,int> LMin = {1e9,1e9},RMin = {1e9,1e9};
    if (a<=M) LMin = Query(node*2,L,M,a,b);
    if (M+1<=b) RMin = Query(node*2+1,M+1,R,a,b);
    return min(LMin,RMin);
}

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);
    }
    Euler.push_back(0);
    DFS(1);
    int N = Euler.size()-1;
    v.push_back({0,0});
    for (int i=1;i<=N;++i){
        int x = Euler[i];
        v.push_back({lvl[x],x});
    }
    Build(1,1,N);
    vector <int> st(N+5,0);
    for (int i=1;i<=N;++i){
        int x = Euler[i];
        //cout << i << ": " << x << ' ' << lvl[x] << '\n';
        if (st[x]==0){
            st[x] = i;
        }
    }
    /*
    cout << "\n\n";
    cout << Query(1,1,N,1,2).second << '\n';
    cout << "\n\n";
    */
    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);
        //cout << L << ' ' << R << '\n';
        pair <int,int> ans = Query(1,1,N,L,R);
        fout << ans.second << '\n';
    }
    return 0;
}