Cod sursa(job #2565493)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 2 martie 2020 14:26:42
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.8 kb
#include <bits/stdc++.h>
using namespace std;

const int DIM = 100005;
const int LGM = 17;

int anc[DIM][LGM], lev[DIM];
vector<int> edg[DIM];

class InputReader {
private:
    static const int SIZE = 1 << 14;
    char buf[SIZE]; int ptr; FILE *inFile;

    inline void advance(void) {
        if (++ptr == SIZE) {
            ptr = 0;
            fread(buf, SIZE, 1, inFile);
        }
    }

    inline char current(void) {
        return buf[ptr];
    }
public:
    InputReader(const char *fileName) {
        inFile = fopen(fileName, "r");
        ptr = 0; fread(buf, SIZE, 1, inFile);
    }

    InputReader &operator >>(int &val) {
        val = 0;
        while (current() < '0' || current() > '9')
            advance();
        while (current() >= '0' && current() <= '9') {
            val = val * 10 + (current() - '0');
            advance();
        }
        return *this;
    }
} in("lca.in");
ofstream out("lca.out");

int lca(int x, int y) {
    if (lev[x] > lev[y])
        swap(x, y);
    for (int l = LGM - 1; l >= 0; --l)
        if (lev[y] - (1 << l) >= lev[x])
            y = anc[y][l];
    for (int l = LGM - 1; l >= 0; --l)
        if (anc[x][l] != anc[y][l])
            x = anc[x][l], y = anc[y][l];
    if (x == y)
        return x;
    return anc[x][0];
}

void dfs(int x, int f) {
    lev[x] = lev[f] + 1;
    for (int l = 1; l < LGM; ++l)
        anc[x][l] = anc[anc[x][l - 1]][l - 1];
    for (int y : edg[x])
        dfs(y, x);
}

int main(void) {
    ios::sync_with_stdio(false);
    int n, m; in >> n >> m;
    for (int i = 2; i <= n; ++i) {
        in >> anc[i][0];
        edg[anc[i][0]].push_back(i);
    }
    dfs(1, 0);
    while (m--) {
        int x, y; in >> x >> y;
        out << lca(x, y) << "\n";
    }
    return 0;
}