Cod sursa(job #2641089)

Utilizator PatrickCplusplusPatrick Kristian Ondreovici PatrickCplusplus Data 9 august 2020 23:55:02
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int const nmax = 100005;
int n, m, z, ap[nmax * 3], r[17][nmax * 3], lg[nmax * 3];
pair <int, int> v[nmax * 3];
vector <int> G[nmax];
void Read(){
    fin >> n >> m;
    for (int i = 2; i <= n; ++i){
        int parinte;
        fin >> parinte;
        G[parinte].push_back(i);
    }
}
void Dfs(int nod, int nivel){
    v[++z] = {nod, nivel};
    r[0][z] = z;
    ap[nod] = z;
    for (auto vecin : G[nod]){
        Dfs(vecin, nivel + 1);
        v[++z] = {nod, nivel};
        r[0][z] = z;
    }
}
void Rmq(){
    for (int i = 2; i <= z; ++i) lg[i] = 1 + lg[i / 2];
    for (int j = 1; (1 << j) <= z; ++j){
        for (int i = 1; i + (1 << j) - 1 <= z; ++i){
            r[j][i] = r[j - 1][i];
            if (v[r[j - 1][i + (1 << (j - 1))]].second < v[r[j - 1][i]].second){
                r[j][i] = r[j - 1][i + (1 << (j - 1))];
            }
        }
    }
}
int lca(int a, int b){
    if (ap[a] > ap[b]) swap(a, b);
    a = ap[a];
    b = ap[b];
    int diff = b - a + 1;
    int l = lg[diff];
    int minim = r[l][a];
    if (v[r[l][b - (1 << l) + 1]].second < v[r[l][a]].second){
        minim = r[l][b - (1 << l) + 1];
    }
    return v[minim].first;

}
void Solve(){
    while (m--){
        int x, y;
        fin >> x >> y;
        fout << lca(x, y) << "\n";
    }
}
int main(){
    Read();
    Dfs(1, 0);
    Rmq();
    Solve();
    fin.close();
    fout.close();
    return 0;
}