Cod sursa(job #605533)

Utilizator SpiderManSimoiu Robert SpiderMan Data 30 iulie 2011 17:33:28
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
# include <cstdio>
# include <algorithm>
# include <vector>
using namespace std;

# define x first
# define y second

const char *FIN = "lca.in", *FOU = "lca.out";
const int MAX = 100005;

vector <int> G[MAX];
vector < pair <int, int> > Q;
int N, M, lun[MAX << 1], RMQ[20][MAX << 2], ap[MAX];

void dfs (int S, int L) {
    Q.push_back (make_pair (S, L)), ap[S] = Q.size () - 1;
    for (vector <int> :: iterator it = G[S].begin (); it != G[S].end (); ++it) {
        dfs (*it, L + 1);
        Q.push_back (make_pair (S, L));
    }
}

void rmq (void) {
    int size = Q.size () - 1;
    for (int i = 2; i <= size; ++i)
        lun[i] = lun[i >> 1] + 1, RMQ[0][i] = i;
    RMQ[0][1] = 1;
    for (int i = 1; 1 << i < size; ++i)
        for (int j = 1; j <= size - (1 << i); ++j) {
            int k = 1 << i - 1;
            RMQ[i][j] = RMQ[i - 1][j];
            if (Q[RMQ[i - 1][j + k]].y < Q[RMQ[i][j]].y)
                RMQ[i][j] = RMQ[i - 1][j + k];
        }
}

inline int lca (int x, int y) {
    int st = ap[x], dr = ap[y];
    if (st > dr) swap (st, dr);
    int sol = RMQ[lun[dr - st + 1]][st];
    if (Q[sol].y > Q[RMQ[lun[dr - st + 1]][st + ((dr - st + 1) - (1 << lun[dr - st + 1]))]].y)
        sol = RMQ[lun[dr - st + 1]][st + ((dr - st + 1) - (1 << lun[dr - st + 1]))];
    return Q[sol].x;
}

int main (void) {
    freopen (FIN, "r", stdin);
    freopen (FOU, "w", stdout);

    scanf ("%d %d", &N, &M);
    for (int i = 2, x; i <= N; ++i) {
        scanf ("%d", &x);
        G[x].push_back (i);
    }
    Q.push_back (make_pair (0, 0)), dfs (1, 0), rmq ();
    for (int i = 1, x, y; i <= M; ++i) {
        scanf ("%d %d", &x, &y);
        printf ("%d\n", lca (x, y));
    }
}