Cod sursa(job #1144554)

Utilizator swim406Teudan Adina swim406 Data 17 martie 2014 11:51:32
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.67 kb
#include <stdio.h>
#include <vector>
#define NMAX 200009

using namespace std;

vector <int> G[NMAX];
int euler[2*NMAX];
int depth[NMAX];
int first[NMAX];
int M[NMAX][50];
int lg[2*NMAX];
int N, m;

void rmq () {
    int i, j;
    for (i = 2; i < 2*N; ++i)
        lg[i] = lg[i/2] + 1;
    for (i = 1; i < 2*N; ++i)
        M[i][0] = i;
    for (j = 1; (1<<j) < 2*N; ++j)
        for (i = 1; i + (1<<j) - 1 < 2*N; ++i)
            if (depth[ euler[ M[i][j-1] ] ] < depth[ euler[ M[i+(1<<(j-1)) ] [j-1] ] ])
                M[i][j] = M[i][j-1];
            else M[i][j] = M[i+(1<<(j-1))][j-1];
}

void dfs (int nod) {
    euler[++euler[0]] = nod;
    if (!first[nod]) first[nod] = euler[0];
    int ok = 0;
    for (vector<int>::iterator it = G[nod].begin(); it != G[nod].end(); ++it) {
        depth[*it] = depth[nod] + 1;
        dfs (*it);
        if (euler[euler[0]] != nod)
            euler[++euler[0]] = nod;
    }
}

int main() {
    freopen ("lca.in", "r", stdin);
    freopen ("lca.out", "w", stdout);
    int i, x, y, nod, k, aux;
    int tata[NMAX];
    scanf ("%d %d", &N, &m);
    tata[1] = 0;
    for (i = 2; i <= N; ++i) {
        scanf ("%d", &tata[i]);
        G[tata[i]].push_back(i);
    }
    dfs(1);
    rmq();
    for (i = 1; i <= m; ++i) {
        scanf ("%d %d", &x, &y);
        x = first[x], y = first[y];
        if (y < x) {
            aux = x;
            x = y;
            y = aux;
        }
        k = lg[y-x+1];
        if (depth[euler[M[x][k]]] < depth[euler[M[y - (1<<k) + 1][k]]])
            printf ("%d\n", euler[M[x][k]]);
        else printf ("%d\n", euler[M[y-(1<<k)+1][k]]);
    }
    return 0;
}