Cod sursa(job #2713837)

Utilizator PatrickCplusplusPatrick Kristian Ondreovici PatrickCplusplus Data 28 februarie 2021 18:51:07
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.57 kb
#include <bits/stdc++.h>

using namespace std;

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

const int nmax = 100005;
int n, m, v[nmax * 2 + 6], z, rmq[nmax * 2 + 6][20], ap[nmax], nv[nmax * 2 + 6], lg[nmax * 2 + 6];
vector <int> G[nmax];

void dfs(int nod, int nivel){
    v[++z] = nod;
    nv[z] = nivel;
    ap[nod] = z;
    for (auto it : G[nod]){
        dfs(it, nivel + 1);
        v[++z] = nod;
        nv[z] = nivel;
    }
}

void Lca(int x, int y){
    if (x > y){
        swap(x, y);
    }
    int diff = y - x + 1;
    int l = lg[diff];
    int index1 = rmq[x][l];
    int index2 = rmq[y - (1 << l) + 1][l];
    if (nv[index1] < nv[index2]){
        fout << v[index1] << "\n";
    }
    else{
        fout << v[index2] << "\n";
    }
}

int main(){
    fin >> n >> m;
    for (int i = 2; i <= n; ++i){
        int x;
        fin >> x;
        G[x].push_back(i);
    }
    dfs(1, 0);
    for (int i = 1; i <= z; ++i){
        rmq[i][0] = i;
        if (i > 1){
            lg[i] = 1 + lg[i / 2];
        }
    }
    for (int i = 1; (1 << i) <= z; ++i){
        for (int j = 1; j + (1 << i) - 1 <= z; ++j){
            int index1 = rmq[j][i - 1];
            int index2 = rmq[j + (1 << (i - 1))][i - 1];
            if (nv[index1] < nv[index2]){
                rmq[j][i] = rmq[j][i - 1];
            }
            else{
                rmq[j][i] = rmq[j + (1 << (i - 1))][i - 1];
            }
        }
    }
    while (m--){
        int x, y;
        fin >> x >> y;
        Lca(ap[x], ap[y]);
    }
    return 0;
}