Cod sursa(job #1189809)

Utilizator mihai995mihai995 mihai995 Data 23 mai 2014 16:27:56
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.3 kb
#include <fstream>
#include <vector>
using namespace std;

const int N = 1 + 1e5, LG = 17;

int rmq[1 + LG][2 * N], depth[N], start[N], timp, n;
vector<int> tree[N];

void dfs(int x){
    start[x] = timp;
    rmq[0][ timp++ ] = x;

    for (auto it = tree[x].begin() ; it != tree[x].end() ; it++)
        if (depth[*it] == 0){
            depth[*it] = 1 + depth[x];
            dfs(*it);
            rmq[0][ timp++ ] = x;
        }
}

inline int best(int x, int y){
    return depth[x] < depth[y] ? x : y;
}

int lca(int x, int y){
    x = start[x]; y = start[y];
    if (x > y) swap(x, y);

    int L = 31 - __builtin_clz(y - x + 1);
    return best(rmq[L][x], rmq[L][y - (1 << L) + 1]);
}

void compute(){
    depth[1] = 1;
    dfs(1);

    for (int i = 1, step = 1 ; i <= LG ; i++, step <<= 1)
        for (int j = 0 ; j + step < timp ; j++)
            rmq[i][j] = best(rmq[i - 1][j], rmq[i - 1][j + step]);
}

int main(){
    int nrQ, x, y;
    ifstream in("lca.in");

    in >> n >> nrQ;
    for (int i = 2 ; i <= n ; i++){
        in >> x;
        tree[ x ].push_back(i);
    }

    compute();

    ofstream out("lca.out");

    while (nrQ--){
        in >> x >> y;
        out << lca(x, y) << '\n';
    }

    in.close();
    out.close();

    return 0;
}