Cod sursa(job #2188665)

Utilizator savigunFeleaga Dragos-George savigun Data 27 martie 2018 12:31:28
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.06 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

const int BUF_SIZE = 20000000;
int ptr, out_ptr;
char buf[BUF_SIZE], out_buf[BUF_SIZE];

const int MAXN = 100005;
int n, m;
int log[MAXN], T[MAXN], dp[17][MAXN], lvl[MAXN];
vector<int> g[MAXN];

int next_int() {
    int nr = 0;
    while (!isdigit(buf[ptr])) ptr++;
    while (isdigit(buf[ptr])) {
        nr = nr * 10 + (buf[ptr] - '0');
        ptr++;
    }
    return nr;
}

void write_int(int nr, bool space = true, bool nl = false) {
    if (nr == 0) return;
    write_int(nr / 10, 0);
    out_buf[out_ptr++] = nr % 10 + '0';
    if (space) out_buf[out_ptr++] = ' ';
    if (nl) out_buf[out_ptr++] = '\n';
}

void preprocess() {
    log[1] = 0;
    for (int i = 2; i <= 100000; ++i) {
        log[i] = log[i / 2] + 1;
    }

    for (int i = 1; i <= n; ++i) dp[0][i] = T[i];
    for (int k = 1; k <= 16; ++k) {
        for (int i = 1; i <= n; ++i) {
            dp[k][i] = dp[k - 1][dp[k - 1][i]];
        }
    }
}

void dfs(int x, int level) {
    lvl[x] = level;
    for (int &y : g[x]) {
        dfs(y, level + 1);
    }
}

int query(int p, int q) {
    if (lvl[q] < lvl[p]) {
        int aux = p;
        p = q;
        q = aux;
    }

    for (int i = log[lvl[q] - lvl[p] + 1]; i >= 0; --i) {
        if (lvl[dp[i][q]] >= lvl[p]) q = dp[i][q];
    }

    if (p == q) return p;

    for (int i = log[lvl[p]]; i >= 0; --i) {
        if (dp[i][p] != dp[i][q]) {
            p = dp[i][p];
            q = dp[i][q];
        }
    }

    return T[p];
}

int main()
{
    fin.read(buf, BUF_SIZE);
    n = next_int();
    m = next_int();
    for (int i = 2; i <= n; ++i) {
        T[i] = next_int();
        g[T[i]].push_back(i);
    }

    preprocess();
    dfs(1, 1);

    for (int i = 1, p, q; i <= m; ++i) {
        p = next_int();
        q = next_int();
        write_int(query(p, q), false, true);
    }

    out_buf[out_ptr] = 0;
    fout << out_buf;

    return 0;
}