Cod sursa(job #2607231)

Utilizator minecraft3Vintila Valentin Ioan minecraft3 Data 29 aprilie 2020 15:56:47
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.19 kb
#include <bits/stdc++.h>

using namespace std;

#define M 4000005
#define N 100005
#define L 17

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

int val[M], urm[M], lst[N], nr;
int ti[N], to[N], t[17][N], timp;
int n;

void add_graph(int x, int y) {
    val[++nr] = y;
    urm[nr] = lst[x];
    lst[x] = nr;
}

void precalc() {
    for(int i = 1; i <= L; ++i)
        for(int j = 1; j <= n; ++j)
            t[i][j] = t[i-1][t[i-1][j]];
}

int lca(int x, int y) {
    /*
    t[i][j] = al 2 la i-lea stramos al lui j
    for(int i = 1; i < L; ++i)
        t[i][j] = t[i-1][t[i-1][j]]
    */
    int pos = L - 1;
    while(pos >= 0) {
        int s = t[pos][x];
        if(s != 0 && (ti[s] > ti[y] || to[y] > to[s]))
            x = s;
        --pos;
    }
    return t[0][x];
}

void dfs(int x) {
    ti[x] = ++timp;
    for(int p = lst[x]; p; p = urm[p]) {
        int y = val[p];
        if(!ti[y]) { dfs(y); t[0][y] = x; }
    }
    to[x] = ++timp;
}

int main() {
    int m, x, y;
    fin >> n >> m;
    for(int i = 2; i <= n; ++i) {
        fin >> x;
        add_graph(x, i);
        add_graph(i, x);
    } dfs(1); precalc(); do {
        fin >> x >> y;
        fout << lca(x, y) << '\n';
    } while(--m);

}