Cod sursa(job #2188580)

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

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

const int BUFF_SIZE = 25000000;
int ptr;
char buff[BUFF_SIZE];

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

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

void preprocess() {
    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]) swap(p, q);

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

    if (p == q) return p;

    for (int i = 16; 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(buff, BUFF_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();
        fout << query(p, q) << "\n";
    }

    return 0;
}