Cod sursa(job #2813027)

Utilizator BlueLuca888Girbovan Robert Luca BlueLuca888 Data 5 decembrie 2021 17:20:22
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.48 kb
#include <bits/stdc++.h>

using namespace std;

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

const int DIM = 100005;
vector <int> v[DIM];
int n, q, tata;

int m, euler[2*DIM], level[2*DIM], freq[DIM];
void set_eul(int nod, int lvl){
    euler[++m] = nod;
    level[m] = lvl;
    freq[nod] = m;
    for(int i=0; i < (int)v[nod].size(); i++){
        set_eul(v[nod][i], lvl+1);
        euler[++m] = nod;
        level[m] = lvl;
    }
}

int rmq[2*DIM][18];
void set_rmq(){
    for(int i=1; i<=m; i++)
        rmq[i][0] = i;

    int lft, rgt;
    for(int j=1; (1<<j) <= m; j++)
        for(int i=1, ii; (ii = i+(1<<j-1)) <= m; i++){
            lft = rmq[i][j-1];
            rgt = rmq[ii][j-1];
            rmq[i][j] = (level[lft] < level[rgt] ? lft : rgt);
        }
}

int lg2[2*DIM];
void set_lg2(){
    lg2[0] = lg2[1]=0;
    for(int i=2; i<=m; i++)
        lg2[i] = lg2[i>>1] + 1;
}

int main (){
    fin>>n>>q;
    for(int i=2; i<=n; i++){
        fin>>tata;
        v[tata].push_back(i);
    }

    set_eul(1, 1);
    set_rmq();
    set_lg2();

    int x, y, lft, rgt, len;
    while(q--){
        fin>>x>>y;
        lft = min(freq[x], freq[y]);
        rgt = max(freq[x], freq[y]);
        len = lg2[rgt - lft + 1];
        x = rmq[lft][len];
        y = rmq[rgt-(1<<len)+1][len];

        if(level[x] < level[y])
            fout<<euler[x];
        else
            fout<<euler[y];
        fout<<"\n";
    }
    return 0;
}