Cod sursa(job #1500687)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 12 octombrie 2015 16:19:04
Problema Lowest Common Ancestor Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.57 kb
#include <cstdio>
#include <cmath>

using namespace std;

const int Nmax = (int) 1e5;
const int NIL = -1;

struct List {
    int v, next;
};

List l[Nmax];
int adj[Nmax];

int father[Nmax], d[Nmax], gr[Nmax];
int sqrtN;

void inline addEdge(int u, int v, int pos) {
    l[pos].v = v;
    l[pos].next = adj[u];
    adj[u] = pos;
}

void DFS(int u, int depth, int group) {
    d[u] = depth;
    gr[u] = group;

    if (depth % sqrtN == 0) {
        group = u;
    }

    for (int i = adj[u]; i != NIL; i = l[i].next) {
        int v = l[i].v;
        if (father[v] == NIL) {
            father[v] = u;
            DFS(v, depth + 1, group);
        }
    }
}

int lca(int u, int v) {
    while (gr[u] != gr[v]) {
        if (d[u] > d[v]) {
            u = gr[u];
        } else {
            v = gr[v];
        }
    }
    while (u != v) {
        if (d[u] > d[v]) {
            u = father[u];
        } else {
            v = father[v];
        }
    }
    return u;
}

int main(void) {
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    int n, m;
    int u, v;

    scanf("%d%d", &n, &m);

    for (int i = 0; i < n; i++) {
        adj[i] = NIL;
        father[i] = NIL;
    }
    for (int i = 1; i < n; i++) {
        scanf("%d", &u);
        addEdge(u - 1, i, i);
    }

    sqrtN = (int) sqrt(n - 1) + 1;
    DFS(0, 1, 0);

    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        printf("%d\n", lca(u - 1, v - 1) + 1);
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}