Cod sursa(job #3294933)

Utilizator diana_dd03Dorneanu Diana diana_dd03 Data 30 aprilie 2025 13:54:44
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.4 kb
#include <bits/stdc++.h>
using namespace std;

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

const int NMAX=100005;

int N, M, sz;
int tati[NMAX];
int rmq[NMAX][20];
vector<int>L[NMAX];
int e[2*NMAX];
int niv[2*NMAX];
int poz_e[2*NMAX];

void Euler(int nod, int lvl){
    e[sz]=nod;
    niv[sz]=lvl;
    poz_e[nod]=sz;
    sz++;
    for(int fiu : L[nod]){
        Euler(fiu, lvl+1);
        e[sz]=nod;
        niv[sz]=lvl;
        sz++;
    }
}

void calc_rmq(int n){
    for(int i = 0; i < n; i++)
        rmq[i][0]=i;
    for(int j = 1; j <= log2(n); j++){
            for(int i = 0; i <= n - (1<<j); i++){
                if(niv[rmq[i][j-1]] < niv[rmq[i + (1<<(j-1))][j-1]])
                    rmq[i][j]=rmq[i][j-1];
                else
                    rmq[i][j]=rmq[i + (1<<(j-1))][j-1];
        }
    }
}

int query(int x, int y){
  if(x>y)
    swap(x, y);
  int k = int(log2(y-x+1));
  if(niv[rmq[x][k]] < niv[rmq[y-(1<<k) + 1][k]])
     return rmq[x][k];
  return rmq[y-(1<<k) + 1][k];

}
int main(){
    fin>>N>>M;
    for(int i=1;i<N;i++){
        int j;
        fin>>j;
        L[j-1].push_back(i);
    }
    Euler(0, 0);
    /*for(int i=0;i<sz;i++){
        cout<<e[i]+1<<" ";
    }*/
    calc_rmq(sz);
    for(int i=0;i<M;i++){
        int x, y;
        fin>>x>>y;
        fout<<e[query(poz_e[x-1], poz_e[y-1])]+1<<"\n";
    }
    return 0;
}