Cod sursa(job #2639739)

Utilizator buhaidarius@gmail.comBuhai Darius [email protected] Data 3 august 2020 17:08:51
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.46 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <cmath>

const int NMAX=(int)1e5+1;

using namespace std;

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

int n, m;
map<int, vector<int>> sons;
vector<pair<int, int>> euler;
int v[3*NMAX][20];
int first[NMAX];

void read(){
    fin>>n>>m;
    for(int i=2;i<=n;i++){
        int x;
        fin>>x;
        sons[x].push_back(i);
    }
}

void exec_euler(int dad = 1, int lvl = 0){
    first[dad]=(int)euler.size();
    euler.emplace_back(dad, lvl);
    for(auto son : sons[dad]){
        exec_euler(son, lvl+1);
        euler.emplace_back(dad, lvl);
    }
}

void exec_rmq(){
    n = euler.size();
    for(int i=0;i<n;i++)
        v[i][0] = i;
    int pow = 1;
    for(int j=1;pow*2<=n;j++){
        for(int i=0;i+pow*2-1<n;i++){
            if(euler[v[i][j-1]].second<euler[v[i+pow][j-1]].second)
                v[i][j] = v[i][j-1];
            else
                v[i][j] = v[i+pow][j-1];
        }
        pow*=2;
    }
}

int min_rmq(int x, int y){
    int lg = static_cast<int>(log2(y-x+1));
    if(euler[v[x][lg]].second<euler[v[y-(1<<lg)+1][lg]].second)
        return euler[v[x][lg]].first;
    return euler[v[y-(1<<lg)+1][lg]].first;
}


void exec(){
    int a, b;
    while(m--){
        fin>>a>>b;
        a = first[a];
        b = first[b];
        if(b<a) swap(a, b);
        fout<<min_rmq(a, b)<<'\n';
    }
}

int main() {
    read();
    exec_euler();
    exec_rmq();
    exec();
    return 0;
}