Cod sursa(job #1971252)

Utilizator mariakKapros Maria mariak Data 20 aprilie 2017 01:25:32
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.44 kb
#include <bits/stdc++.h>
#define maxN 100002
#define log 18

FILE *fin = freopen("lca.in", "r", stdin);
FILE *fout = freopen("lca.out", "w", stdout);

using namespace std;
int N, M;
int Anc[log][maxN], lvl[maxN];
vector <int> G[maxN];

void init(){
    for(int i = 0; i < log; ++ i)
        for(int j = 1; j <= N; ++ j)
            Anc[i][j] = -1;
}

void compute_Anc(int node){
    for(int i = 1; i < log; ++ i)
            if(Anc[i - 1][node] != -1)
                Anc[i][node] = Anc[i - 1][Anc[i - 1][node]];
}

void dfs(int node){
    compute_Anc(node);
    for(int son : G[node])
        if(lvl[son] == 0 && son != 1){
            lvl[son] = lvl[node] + 1;
            dfs(son);
        }
}

int Lca(int u, int v){
    if(lvl[u] > lvl[v])
        swap(u, v);
    for(int i = log - 1; i >= 0; -- i)
        if(Anc[i][v] != -1 && lvl[Anc[i][v]] >= lvl[u])
            v = Anc[i][v];
    if(u == v)
        return u;
    for(int i = log - 1; i >= 0; -- i)
        if(Anc[i][v] != -1 && Anc[i][v] != Anc[i][u])
            v = Anc[i][v], u = Anc[i][u];
    return Anc[0][u];
}

int main(){
    scanf("%d %d", &N, &M);
    init();
    for(int i = 2; i <= N; ++ i){
        scanf("%d", &Anc[0][i]);
        G[Anc[0][i]].push_back(i);
        G[i].push_back(Anc[0][i]);
    }

    dfs(1);
    while(M --){
        int u, v;
        scanf("%d %d", &u, &v);
        printf("%d\n", Lca(u, v));
    }
    return 0;
}