Cod sursa(job #1189881)

Utilizator mihai995mihai995 mihai995 Data 23 mai 2014 19:33:14
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <fstream>
#include <vector>
using namespace std;

#define forit(it,v) for (auto it = v.begin() ; it != v.end() ; it++)

const int N = 1 + 1e5, LGLG = 5;

int head[LGLG][N], n;
int start[N], stop[N], timp;
vector<int> tree[N];

void mark(int x, int H){
    head[0][x] = H;
    forit(it, tree[x])
        if ( !head[0][*it] )
            mark(*it, H);
}

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

    int weight = 1, best = -1, val, son;
    forit(it, tree[x]){
        val = dfs(*it);
        weight += val;
        if (best < val){
            best = val;
            son = *it;
        }
    }
    forit(it, tree[x])
        if (*it != son)
            mark(*it, x);
    stop[x] = ++timp;

    return weight;
}

inline int isAncestor(int T, int x){
    return start[T] <= start[x] && stop[x] <= stop[T];
}

int dumbLCA(int x, int y){
    if ( isAncestor(x, y) )
        return x;
    for (int i = LGLG - 1 ; i >= 0 ; i--)
        if ( !isAncestor(head[i][x], y) )
            x = head[i][x];
    return head[0][x];
}

int lca(int x, int y){
    int X = dumbLCA(x, y), Y = dumbLCA(y, x);
    return isAncestor(Y, X) ? X : Y;
}

void compute(){
    dfs(1);
    mark(1, 1);

    for (int i = 1 ; i < LGLG ; i++)
        for (int j = 1 ; j <= n ; j++)
            head[i][j] = head[i - 1][ head[i - 1][j] ];
}

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;
}