Cod sursa(job #1708713)

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

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

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

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

void buildRMQ() {

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

    lgmax = log2( euler[ 0 ] );
    for (int k = 1; k <= lgmax; ++k) {
        int imax = euler[ 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) {
    int st = fst[x], dr = fst[y];
    if (st > dr) {
        swap(st, dr);
    }
    int k = lg[ dr - st + 1];
    x = rmq[ k - 1][ st ], y = rmq[ k - 1 ][ 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;
}