Cod sursa(job #2432567)

Utilizator Bulboaca_EugenBulboaca Alexandru Eugen Bulboaca_Eugen Data 24 iunie 2019 13:05:52
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.7 kb
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 10 * 1e4 + 15;
const int LOGMAX = 25;
const int INF = 1e8;
int dist[MAXN], first[MAXN], euler[2 * MAXN], rmq[LOGMAX][2 * MAXN], lg[MAXN], lung;
///cel de-al i-lea număr reprezentând tatăl nodului i+1
vector <int> g[MAXN];
ifstream fin("lca.in");
ofstream fout("lca.out");
void buildLOG(){
    for(int i = 0; i < lung; ++i)
        rmq[0][i] = euler[i];
    for(int i = 2; i <= lung; ++i)
        lg[i] = lg[i / 2] + 1;
}
void buildEuler(int node, int papa){
    euler[++lung] = node;
    first[node] = lung;
    dist[node] = dist[papa] + 1;
    for(auto y : g[node]){
        if(y != papa) {
            buildEuler(y, node);
            euler[++lung] = node;
        }
    }
}
void buildRMQ(){
    for(int i = 1; (1 << i) < lung; ++i){
        for(int j = 0; j + (1 << i) - 1 < lung; ++j){
            if(dist[rmq[i - 1][j]] <= dist[rmq[i - 1][j + (1 << (i - 1))]])
               rmq[i][j] = rmq[i - 1][j];
            else rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
        }
    }
}
int lca(int x, int y){
    int st = first[x];
    int dr = first[y];
    if(st > dr) swap(st, dr);
    int logaritm = lg[dr - st + 1];
    if(dist[rmq[logaritm][st]] <= dist[rmq[logaritm][dr - (1 << logaritm) + 1]])
        return rmq[logaritm][st];
    return rmq[logaritm][dr - (1 << logaritm) + 1];
}
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);
    }
    buildEuler(1, 0);
    buildLOG();
    buildRMQ();
    for(int i = 1; i <= m; ++i){
        int x, y;
        fin >> x >> y;
        fout << lca(x, y) << '\n';
    }
    return 0;
}