Cod sursa(job #2399275)

Utilizator lupulescu2001Lupulescu Vlad lupulescu2001 Data 7 aprilie 2019 11:26:03
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.5 kb
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

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

const int nMax = 100000;
vector<int> g[nMax + 5];
int n, m, v[2 * nMax + 5];
int lca[nMax + 5], dim;
int lvl[2 * nMax + 5];
int rmq[20][nMax * 2 + 5];
int lg[2 * nMax + 5];

void DFS(int nod, int lev) {
    v[++dim] = nod;
    lvl[dim] = lev;
    lca[nod] = dim;
    for (auto i : g[nod]) {
        DFS(i, lev + 1);
        v[++dim] = nod;
        lvl[dim] = lev;
    }
}

void RMQ() {
    for (int i = 2; i <= dim; i++)
        lg[i] = lg[i >> 1] + 1;
    for (int i = 1; i <= dim; i++)
        rmq[0][i] = i;
    for (int i = 1; (1 << i) < dim; i++)
        for (int j = 1; j <= dim - (1 << i); j++) {
            int k = 1 << (i - 1);
            rmq[i][j] = rmq[i - 1][j];
            if (lvl[rmq[i - 1][j + k]] < lvl[rmq[i][j]])
                rmq[i][j] = rmq[i - 1][j + k];
        }
}

int LCA(int x, int y) {
    int a = lca[x], b = lca[y];
    if (a > b)
        swap(a, b);
    int dif = b - a + 1;
    int p = lg[dif];
    int st = rmq[p][a], dr = rmq[p][b - (1 << p) + 1];
    if (lvl[st] > lvl[dr])
        return v[dr];
    return v[st];
}

int main() {
    fin >> n >> m;
    for (int i = 2; i <= n; i++) {
        int x;
        fin >> x;
        g[x].push_back(i);
    }
    DFS(1, 0);
    RMQ();
    for (int i = 1; i <= m; i++) {
        int x, y;
        fin >> x >> y;
        fout << LCA(x, y) << '\n';
    }
}