Cod sursa(job #2929386)

Utilizator Paul281881818818181991919191881818Draghici Paul Paul281881818818181991919191881818 Data 25 octombrie 2022 19:12:39
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.81 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <cmath>
#define NMAX 100002
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int block_sz;
int level[NMAX];
int parent[NMAX];
int jump_parent[NMAX];

vector<int> V[NMAX];
int n, m;
void DFS(int curr, int prev){
    level[curr] = prev + 1;
    parent[curr] = prev;
    if(level[curr] % block_sz == 0){
        jump_parent[curr] = parent[curr];
    }
    else{
        jump_parent[curr] = jump_parent[prev];
    }
    for(int i=0; i<V[curr].size(); i++){
        if(V[curr][i] != prev){
            DFS(V[curr][i], curr);
        }
    }
}
int LCANaive(int u, int v){
    if(u == v){
        return u;
    }
    if(level[u] > level[v])
        swap(u, v);
    v = parent[v];
    return LCANaive(u, v);
}
int LCASqrt(int u, int v){
    while(jump_parent[u] != jump_parent[v]){
        if(level[u] > level[v])
            swap(u, v);
        v = jump_parent[v];
    }
    return LCANaive(u, v);
}
void preprocess(int n){
    block_sz = sqrt(n);
    level[0] = -1;
    DFS(1, 0);
}
int mxLevel = -1; bool viz[NMAX] = {false};
void computeMaxLevel(int node, int level){
    mxLevel = max(mxLevel, level);
    viz[node] = true;
    for(int i=0; i<V[node].size(); i++){
        if(viz[V[node][i]] == false){
            computeMaxLevel(V[node][i], level+1);
        }
    }
}
int main()
{
    fin >> n >> m;
    parent[1] = 0;
    for(int i=2; i<=n; i++){
        int ant;
        fin >> ant;
        parent[i] = ant;
        V[ant].push_back(i);
        V[i].push_back(ant);
    }
    computeMaxLevel(1, 0);
    preprocess(mxLevel);
    for(int q=1; q<=m; q++){
        int node1, node2;
        fin >> node1 >> node2;
        fout << LCASqrt(node1, node2) << '\n';
    }
    return 0;
}