Cod sursa(job #1938495)

Utilizator ifrimencoAlexandru Ifrimenco ifrimenco Data 24 martie 2017 20:44:42
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.58 kb
#include <fstream>
#include <vector>
#include <iostream>
#define NMAX 100002
#define LMAX 20
#define doi_la(i) (1 << i)

using namespace std;

vector <int> v[NMAX];
int rmq[LMAX][NMAX << 2], n, m, lg[NMAX << 1], nivel[NMAX << 1], euler[NMAX << 1], first[NMAX];
int k;
ifstream f("lca.in");
ofstream g("lca.out");

void citire () {
  f >> n >> m;
  int x, i;
  for (i = 2; i <= n; ++i) {
    f >> x;
    v[x].push_back(i);
  }
}

void dfs (int x, int niv) {
    euler[++k] = x;
    nivel[k] = niv;
    first[x] = k;
    vector <int> :: iterator it;
    for (it = v[x].begin(); it != v[x].end(); ++it) {
        dfs(*it, niv+1);
        euler[++k] = x;
        nivel[k] = niv;
    }
}

void rm() {
    int i, j, l;
    for (i = 2; i <= k; ++i)
        lg[i] = lg[i >> 1] + 1;
    for (i = 1; i <= k; ++i)
        rmq[0][i] = i;
    for (i = 1; doi_la(i) < k; ++i)
    for (j = 1; j <= k - doi_la(i); ++j) {
        l = doi_la((i - 1));
        rmq[i][j] = rmq[i - 1][j];
        if (nivel[rmq[i - 1][j+l]] < nivel[rmq[i][j]]) rmq[i][j] = rmq[i - 1][j + l];
    }

}

int lca(int x, int y) {
    int diff, l, sol, sh;
    int a = first[x], b = first[y];
    if (a > b) swap(a, b);
    diff = b - a + 1;
    l = lg[diff];
    sol = rmq[l][a];
    sh = diff - doi_la(l);
    if (nivel[sol] > nivel[rmq[l][a + sh]])
        sol = rmq[l][a + sh];
    return euler[sol];
}

int main()
{
    citire();
    dfs(1, 0);

    rm();
    int x, y;
    for (int i = 1; i <= m; ++i) {
        f >> x >> y;
        g << lca(x, y) << "\n";
    }

    return 0;
}