Cod sursa(job #1708717)

Utilizator UPB_Darius_Rares_SilviuPeace my pants UPB_Darius_Rares_Silviu Data 27 mai 2016 20:46:16
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.83 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cassert>
#define NMAX 100025
#define LOGMAX 40
using namespace std;

int N, Q, level[ NMAX ], e[2 * NMAX], fst[ NMAX ], lg[ 2 * NMAX ], lgmax, rmq[LOGMAX][2 * NMAX];
bitset<NMAX> viz;
vector<int> G[ NMAX ];

void DFS(int node, int l) {
    viz[ node ] = 1;
    level[ node ] = l;
    e[ ++e[0] ] = node;
    fst[ node ] = e[ 0 ];

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

void buildRMQ() {

    for (int i = 2; i <= e[ 0 ]; ++i) {
        lg [ i ] = lg[ i / 2 ] + 1;
    }
    for (int i = 1; i <= e[0]; ++i) {
        rmq[ 0 ][ i ] = e[ i ];
    }

    lgmax = log2( e[ 0 ] );
    for (int k = 1; k <= lgmax; ++k) {
        int imax = e[ 0 ] - (1 << k) + 1;
        for (int i = 1; i <= imax; ++i) {
            int x = rmq[ k - 1][ i ], y = rmq[ k - 1][ i + (1 << (k-1))];
            rmq[ k ][ i ] = (level[ x ] < level[ y ] ? x : y);
        }
    }
}
int lca(int x, int y) {
    if (x == y) {
        return x;
    }
    int st = fst[ x ], dr = fst[ y ];
    if (st > dr) {
        swap(st, dr);
    }

    int k = lg[ dr - st + 1 ];
    x = rmq[ k ][ st ];
    y = rmq[ k  ][ dr - (1 << k ) + 1 ];

    return (level[ x ] < level[ y ] ? x : y);
}
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 );
    }

    DFS(1, 1);
    buildRMQ();


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

    return 0;
}