Cod sursa(job #2249652)

Utilizator AlexutAlex Calinescu Alexut Data 30 septembrie 2018 09:51:05
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.91 kb
#include <iostream>
#include <fstream>
#include <cmath>
#include <math.h>
#include <vector>
#define dMAX 100000

using namespace std;

int n, m, t, p, q;
int first[dMAX * 2 + 2];
int sparseTable[2 * dMAX][(int)log2(2 * dMAX) + 1];

pair<int, int> reprEuler[dMAX * 2 + 2];
int idx;

vector<int> graf[dMAX + 2];

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

void DFS(int v, int niv) {
    reprEuler[++idx] = {v, niv};
    first[v] = idx;
    int newV, u;
    for (u = 0; u < graf[v].size(); u++) {
        newV = graf[v][u];
        DFS(newV, niv + 1);
        reprEuler[++idx] = {v, niv};
    }
}

void MakeTable() {
    int i, j;
    for (i = 1; i <= idx; i++) sparseTable[i][0] = i;
    for (j = 1; (1 << j) <= idx; j++) {
        for (i = 1; i + (1 << j) - 1 <= idx; i++) {
            if (reprEuler[sparseTable[i][j - 1]].second < reprEuler[sparseTable[i + (1 << (j - 1))][j - 1]].second) {
                sparseTable[i][j] = sparseTable[i][j - 1];
            } else
                sparseTable[i][j] = sparseTable[i + (1 << (j - 1))][j - 1];
        }
    }
}

int RMQ(int low, int r) {
    int l = r - low + 1;
    int k = (int)log2(l);
    //return min(reprEuler[sparseTable[low][k]].second, reprEuler[sparseTable[low + l - (1 << k)][k]].second);
    if (reprEuler[sparseTable[low][k]].second < reprEuler[sparseTable[low + l - (1 << k)][k]].second) {
        return reprEuler[sparseTable[low][k]].first;
    } else return reprEuler[sparseTable[low + l - (1 << k)][k]].first;
}

int LCA(int x, int y) {
    int a = first[x], b = first[y];
    if (a > b) swap(a, b);
    return RMQ(a, b);
}

int main()
{
    int i, j;
    fin >> n >> m;
    for (i = 2; i <= n; i++) {
        fin >> t;
        graf[t].push_back(i);
    }
    DFS(1, 0);
    MakeTable();
    for (i = 1; i <= m; i++) {
        fin >> p >> q;
        fout << LCA(p, q) << '\n';
    }
    return 0;
}