Cod sursa(job #1500958)

Utilizator andreea_zahariaAndreea Zaharia andreea_zaharia Data 12 octombrie 2015 22:04:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.85 kb
#include <cstdio>
#include <vector>

using namespace std;

const int NMAX = 100010;
const int logNMAX = 18;

int N, Q;
vector<int> g[NMAX];

int rmq[logNMAX][NMAX * 2];
int lvl[NMAX * 2], euler[NMAX * 2], prim[NMAX * 2], crt;
int log[NMAX * 2];

int DFS (int nod, int niv) {
    euler[++crt] = nod;
    lvl[crt] = niv;
    prim[nod] = crt;

    for (int i = 0; i < g[nod].size (); i++) {
        DFS (g[nod][i], niv + 1);

        euler[++crt] = nod;
        lvl[crt] = niv;
    }
}

void RMQ () {
    log[0] = log[1] = 0;
    log[2] = 1;
    rmq[0][0] = 0;
    rmq[0][1] = 1;
    for (int i = 2; i <= crt; i++) {
        log[i] = log[i / 2] + 1;

        rmq[0][i] = i;
    }

    for (int i = 1; i <= log[crt]; i++) {
        for (int j = 1; j + (1 << i) <= crt + 1; j++) {
            if (lvl[ rmq[i - 1][j] ] < lvl[ rmq[i - 1][j + (1 << (i - 1))] ]) {
                rmq[i][j] = rmq[i - 1][j];
            }
            else {
                rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
            }
        }
    }

}

int LCA (int x, int y) {
    if (prim[y] < prim[x]) {
        int aux = y;
        y = x;
        x = aux;
    }

    int lg = log[prim[y] - prim[x] + 1];
    int ans;
    if (lvl[ rmq[lg][prim[x]] ] < lvl[ rmq[lg][prim[y] - (1 << lg) + 1] ]) {
        ans = euler[ rmq[lg][prim[x]] ];
    }
    else {
        ans = euler[ rmq[lg][prim[y] - (1 << lg) + 1] ];
    }

    return ans;
}

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, 0);
    RMQ ();

    while (Q--) {
        int X, Y;
        scanf ("%d%d", &X, &Y);
        printf ("%d\n", LCA (X, Y));
    }

    return 0;
}