Cod sursa(job #1500693)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 12 octombrie 2015 16:30:44
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.03 kb
#include <cstdio>
#include <cmath>
#include <cctype>

using namespace std;

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

char buffer[BSIZE];
int ptr;

struct List {
    int v, next;
};

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

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

char inline GetChar() {
    if (ptr == BSIZE) {
        fread(buffer, 1, BSIZE, stdin);
        ptr = 0;
    }
    return buffer[ptr++];
}

int inline ReadInt() {
    int q = 0;
    char c;

    do {
        c = GetChar();
    } while (!isdigit(c));
    do {
        q = (10 * q) + (c - '0');
        c = GetChar();
    } while (isdigit(c));
    return q;
}

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;

    n = ReadInt(); m = ReadInt();

    for (int i = 0; i < n; i++) {
        adj[i] = NIL;
        father[i] = NIL;
    }
    for (int i = 1; i < n; i++) {
        u = ReadInt();
        addEdge(u - 1, i, i);
    }

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

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