Cod sursa(job #2288396)

Utilizator berindeiChesa Matei berindei Data 23 noiembrie 2018 12:23:43
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.37 kb
#include <bits/stdc++.h>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int const NMAX=1e5+10;
int const PMAX=33;
int const EMAX=1e7;

int rmq[EMAX][PMAX];
vector< pair<int, int> > euler;
vector<int> gr[NMAX];
int ap[NMAX];

void dfs(int n, int lvl=0){
    euler.push_back({n, lvl});
    if (!ap[n]) ap[n]=euler.size()-1;
    for (auto x: gr[n]){
        dfs(x, lvl+1);
        euler.push_back({n, lvl});
    }
}

int get_ans(int n1, int n2){
    if (n2<n1) swap(n1, n2);
    int log=log2(1.0*n2-n1+1);
    int ans;
    if (euler[rmq[n1][log]].second<euler[rmq[n2-(1<<log)+1][log]].second) ans = rmq[n1][log];
    else ans=rmq[n2-(1<<log)+1][log];
    return euler[ans].first;
}

int main(){
    int n, q;
    int nr, n1, n2;
    in >> n >> q;
    for (int i=2; i<=n; i++){
        in >> nr;
        gr[nr].push_back(i);
    }
    euler.push_back({-1, -1});
    dfs(1);
    int m=euler.size()-1;
    for (int i=1; i<=m; i++)
        rmq[i][0]=i;
    for (int p=1; (1<<p)<m; p++){
        for (int i=1; i+(1<<p)-1<=m; i++){
            if (euler[rmq[i][p-1]].second<euler[rmq[i+(1<<(p-1))][p-1]].second)
                rmq[i][p]=rmq[i][p-1];
            else
                rmq[i][p]=rmq[i+(1<<(p-1))][p-1];
        }
    }

    while (q--){
        in >> n1 >> n2;
        out << get_ans(ap[n1], ap[n2]) << '\n';
    }
}