Cod sursa(job #1779618)

Utilizator al.mocanuAlexandru Mocanu al.mocanu Data 15 octombrie 2016 14:48:33
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.43 kb
#include <stdio.h>
#include <vector>
#define MAX 100005
using namespace std;

int n, m, a[MAX], x, y, euler[2 * MAX], app[MAX], h[MAX], nr, log[2 * MAX], rmq[20][MAX];
vector<int> l[MAX];
bool viz[MAX];

void dfs(int x, int d){
    euler[++nr] = x;
    if(!app[x])
        app[x] = nr;
    viz[x] = 1;
    h[x] = d;
    for(int i = 0; i < l[x].size(); ++i)
        if(!viz[l[x][i]]){
            dfs(l[x][i], d + 1);
            euler[++nr] = x;
        }
}

void prepare(){
    dfs(1, 0);
    for(int i = 1; i <= nr; ++i){
        rmq[0][i] = euler[i];
        log[i + 1] = log[(i + 1) / 2] + 1;
    }
    for(int i = 1; i <= log[nr]; ++i)
        for(int j = 1; j <= nr - (1<<i) + 1; ++j)
            if(h[rmq[i - 1][j]] < h[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 dx = min(app[x], app[y]), dy = max(app[x], app[y]);
    int d = log[dy - dx];
    if(h[rmq[d][dx]] < h[rmq[d][dy - (1<<d) + 1]])
        return rmq[d][dx];
    else
        return rmq[d][dy - (1<<d) + 1];
}

int main(){
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    scanf("%d%d", &n, &m);
    for(int i = 2; i <= n; ++i){
        scanf("%d", &a[i]);
        l[a[i]].push_back(i);
    }
    prepare();
    for(int i = 0; i < m; ++i){
        scanf("%d%d", &x, &y);
        printf("%d\n", lca(x, y));
    }
    return 0;
}