Cod sursa(job #2355698)

Utilizator mihai_brodschiMihai Brodschi mihai_brodschi Data 26 februarie 2019 11:37:18
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.46 kb
#include <cstdio>

using namespace std;

int min(int a, int b) {
    return (a < b ? a : b);
}

struct euler {
    int v;
    euler *ts;

    euler() {
        v = 0;
        ts = nullptr;
    }
};

struct ends {
    euler *first;
    euler *last;

    ends() {
        first = nullptr;
        last = nullptr;
    }
};

int main() {
    euler e1, *aux;
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    int n, m, k = 1;
    scanf("%d %d\n", &n, &m);
    int *p = new int[2 * n + 2]();
    euler* e = new euler[2 * n + 1]();
    ends* inst = new ends[n + 1]();
    for (int i = 1; i < n; i++)
        scanf("%d", &p[i + 1]);
    for (int i = 2; i <= n; i++) {
        if (inst[p[i]].first == nullptr) {
            e[k].v = p[i];
            inst[p[i]].first = &e[k];
            inst[p[i]].last = &e[k];
            k++;
        }
        if (inst[i].first == nullptr) {
            e[k].v = i;
            inst[i].first = &e[k];
            inst[i].last = &e[k];
            k++;
        }
        aux = (*(inst[p[i]].last)).ts;
        (*(inst[p[i]].last)).ts = inst[i].first;
        e[k].v = p[i];
        e[k].ts = aux;
        inst[p[i]].last = &e[k];
        k++;
        (*(inst[i].last)).ts = inst[p[i]].last;
    }
    e1 = *inst[1].first;
    delete[] inst;
    p[1] = 0;
    for (int i = 2; i <= 2 * n + 1; i++) {
        p[i] = p[i / 2] + 1;
    }
    int** a = new int*[p[2 * n + 1] + 1];
    a[0] = new int[2 * n + 1];
    int c = 0;
    int* map = new int[n + 1]();
    while (e1.ts != nullptr) {
        e1 = *e1.ts;
        a[0][c] = e1.v;
        if (!map[e1.v]) {
            map[e1.v] = c + 1;
        }
        c++;
    }
    delete[] e;
    int r = 1;
    for (int i = 1; i <= p[c]; i++) {
        r *= 2;
        a[i] = new int[c - r + 1];
        for (int j = 0; j < c - r + 1; j++) {
            a[i][j] = min(a[i - 1][j], a[i - 1][j + r / 2]);
        }
    }
    int n1, n2;
    for (int i = 0; i < m; i++) {
        scanf("%d %d", &n1, &n2);
        n1 = map[n1] - 1;
        n2 = map[n2] - 1;
        if (n1 > n2) {
            n1 += n2;
            n2 = n1 - n2;
            n1 -= n2;
        }
        r = 1 << p[n2 - n1 + 1];
        printf("%d\n", min(a[p[n2 - n1 + 1]][n1], a[p[n2 - n1 + 1]][n2 - r + 1]));
    }
    for (int i = 0; i <= p[c]; i++) {
        delete[] a[i];
    }
    delete[] a;
    delete[] p;
    delete[] map;
    return 0;
}