Cod sursa(job #2796913)

Utilizator casiannCasian casiann Data 8 noiembrie 2021 23:45:20
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.89 kb
#include <bits/stdc++.h>
using namespace std;

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

#define MAXN 100001
#define MAXLOGN 20

int n, m, nodes[2*MAXN+1], depth[2*MAXN+1], last[MAXN], current_position = 0, a[2*MAXN+1][MAXLOGN], b[2*MAXN+1][MAXLOGN];
vector<vector<int>> children;

void pre_process_rmq(){
    for(int i=1; i<current_position; i++)
        a[i][0] = depth[i];
    for(int j=1; j<MAXLOGN; j++)
        for(int i=1; i<= current_position - (1<<j) + 1; i++){
            a[i][j] = min(a[i][j-1], a[i+(1<<j)][j-1]);
        }
}

void citire(){
    fin >> n >> m;
    children = vector<vector<int>> (n+1);
    for(int i=1; i<n; i++){
        int father;
        fin >> father;
        children[father].push_back(i+1);
    }
}
 
void dfs(int node, int node_depth){
    nodes[current_position] = node;
    depth[current_position] = node_depth;
    last[node] = current_position;
    current_position++;
    for(auto child: children[node]){
        dfs(child, node_depth + 1);
        nodes[current_position] = node;
        depth[current_position] = node_depth;
        last[node] = current_position;
        current_position++;
    }
}

int main(){
    citire();
    // EULERIAN TOUR
    dfs(1, 0);
    // nodes[] -> nodes from Eulerian Tour
    // depth[] -> depth for each node of nodes[]
    // last[]  -> last position of each node in Eulerian Tour
    pre_process_rmq();
    for(int ind=1; ind<=m; ind++){
        int node_st, node_dr, st, dr, length, logg, sol;
        fin >> node_st >> node_dr;
        st = min(last[node_st], last[node_dr]) - 1;
        dr = max(last[node_st], last[node_dr]) - 1 ;
        length = dr-st+1;
        logg = log2(length);
        sol = min(a[st][logg], a[dr-(1<<logg)+1][logg]);
        for(int i=st;i<=dr;i++){
            if(depth[i] == sol) {fout << nodes[i] <<  '\n';break;}
        }
    }
    return 0;
}