Cod sursa(job #1708702)

Utilizator UPB_Darius_Rares_SilviuPeace my pants UPB_Darius_Rares_Silviu Data 27 mai 2016 20:15:12
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.57 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#define NMAX 100009
#define LOGMAX 20
using namespace std;

int N, Q, T[LOGMAX][NMAX], level[NMAX], lgmax;
vector<int> G[ NMAX ];

void DFS(int node, int l) {
    level[ node ] = l;

    for (vector<int>::iterator it = G[node].begin(); it != G[node].end(); ++it) {
        DFS( *it, l + 1);
    }
}

int lca(int x, int y) {
    if (x == y) {
        return x;
    }
    if (level[x] > level[ y ]) {
        swap(x, y);
        // y e mai jos in arbore
    }

    int p = level[ y ] - level[ x ];
    for (int k = 0; k <= lgmax; ++k, p >>= 1) {
        if (p & 1) {
            y = T[ k ][ y ];
        }
    }

    if (x == y) {
        return x;
    }

    // x si y pe acelasi nivel
    p = level[ x ];
    for (int k = p; k >= 0; --k) {
        if (T[ k ][ x ] && T[ k ][ x ] != T[ k ][ y ]) {
            x = T[ k ][ x ];
            y = T[ k ][ y ];
        }
    }

    return T[ 0 ][ x ];
}
int main() {
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

    scanf("%d%d", &N, &Q);
    for (int i = 2; i <= N; ++i) {
        int x;
        scanf("%d", &x);
        G[ x ].push_back( i );
        T[ 0 ][ i ] = x;
    }

    DFS(1, 1);

    lgmax = log2(N);
    for (int k = 1; k <= lgmax; ++k) {
        for (int i = 1; i <= N; ++i) {
            T[ k ][ i ] = T[ k - 1][ T[k - 1][i] ];
        }
    }

    while (Q--) {
        int x, y;
        scanf("%d%d", &x, &y);
        printf("%d\n", lca(x, y));
    }

    return 0;
}