Cod sursa(job #2398423)

Utilizator Bulboaca_EugenBulboaca Alexandru Eugen Bulboaca_Eugen Data 5 aprilie 2019 14:43:22
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.78 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN =  15 + 1e5;

const int LOGMAX = 25;

int euler[2 * MAXN - 1], first[MAXN], dist[MAXN], rmq[2 * MAXN - 1][LOGMAX], last, lg[2 * MAXN - 1];

vector <int> g[MAXN];

void initializare(){

    for(int i = 0; i < last; ++i)

        rmq[i][0] = euler[i];

    for(int i = 2; i <= last; ++i)

        lg[i] = lg[i / 2] + 1;

}

void RangeALG(){

    for(int j = 1; (1 << j) < last; ++j){

        for(int i = 0; i + ( 1 << (j - 1) ) - 1 < last; ++i){

            if(dist[rmq[i][j - 1]] < dist[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];

        }

    }

}

void dfs(int node, int papa){

    euler[++last] = node;

    dist[node] = dist[papa] + 1;

    first[node] = last;

    for(auto y : g[node]) {

        if(y != papa){

            dfs(y, node);

            euler[++last] = node;

        }

    }

}

int query(int st, int dr){

    st = first[st];

    dr = first[dr];

    if(st > dr) swap(st, dr);

    int logaritm = lg[dr - st + 1];

    if(dist[rmq[st][logaritm]] < dist[rmq[dr - (1 << logaritm) + 1][logaritm]])

        return rmq[st][logaritm];

    return rmq[dr - (1 << logaritm) + 1][logaritm];

}

ifstream fin("lca.in");

ofstream fout("lca.out");

int main(){

    int n, m;

    fin >> n >> m;

    for(int i = 0; i < n - 1; ++i){

        int x;

        fin >> x;

        g[x].push_back(i + 2);

    }

    dist[0] = -1;

    dfs(1, 0);

    initializare();

    RangeALG();

    for(int i = 1; i <= m; ++i){

        int x, y;

        fin >> x >> y;

        fout << query(x, y) << '\n';

    }

    return 0;

}