Cod sursa(job #1189756)

Utilizator mihai995mihai995 mihai995 Data 23 mai 2014 13:58:26
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.89 kb
#include <fstream>
#include <vector>
using namespace std;

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

int T[N], son[N], head[LGLG][N], depth[N], heavyDepth[N], n;
vector<int> tree[N];

int dfs(int x){
    int weight = 0, best = -1, val;
    for (auto it = tree[x].begin() ; it != tree[x].end() ; it++){
        depth[*it] = 1 + depth[x];
        val = dfs(*it);
        weight += val;
        if (best < val){
            best = val;
            son[x] = *it;
        }
    }
    return weight;
}

void build(int x, int H, int D){
    heavyDepth[x] = D;
    head[0][x] = H;

    for (auto it = tree[x].begin() ; it != tree[x].end() ; it++)
        if ( son[x] != *it )
            build( *it, *it, D + 1 );
        else
            build( *it, H, D );
}

int heavyAncestor(int x, int nr){
    for (int i = LGLG - 1; i >= 0 ; i--)
        if (nr & (1 << i)){
            nr ^= 1 << i;
            x = T[ head[i][x] ];
        }
    return x;
}

int lca(int x, int y){
    if ( heavyDepth[x] < heavyDepth[y] )
        y = heavyAncestor(y, heavyDepth[y] - heavyDepth[x]);
    else
        x = heavyAncestor(x, heavyDepth[x] - heavyDepth[y]);

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

    return depth[x] < depth[y] ? x : y;
}

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

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

    dfs(1);
    build(1, 1, 1);
    for (int i = 1 ; i < LGLG ; i++)
        for (int j = 1 ; j <= n ; j++)
            head[i][j] =  head[i - 1][ T[ head[i - 1][j] ]  ];

    ofstream out("lca.out");

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

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

    return 0;
}