Cod sursa(job #1985499)

Utilizator rares96cheseliRares Cheseli rares96cheseli Data 27 mai 2017 23:56:55
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.66 kb
#include <bits/stdc++.h>
using namespace std;

#define NMAX 100005
#define k_NMAX 17

ifstream f("lca.in");
ofstream g("lca.out");

int N, M, rmq[k_NMAX + 1][2 * NMAX], _first[NMAX];
int lg[2 * NMAX], euler[2 * NMAX], level[NMAX], eulerSize;
vector < int > G[NMAX];

void readInput() {
    f >> N >> M;
    for (int i = 2; i <= N; ++i) {
        int x;
        f >> x;
        G[x].push_back(i);
    }
}

void dfs(int node, int currentLevel) {
    level[node] = currentLevel;
    euler[++eulerSize] = node;
    _first[node] = eulerSize;

    for (auto it : G[node]) {
        dfs(it, currentLevel + 1);
        euler[++eulerSize]=node;
    }
}

void computeRmq() {
    rmq[0][1] = euler[1];
    for (int i =2 ; i <= eulerSize; ++i) {
        lg[i] = lg[i / 2] + 1;
        rmq[0][i] = euler[i];
    }

    for (int i = 1; (1 << i) <= eulerSize; ++i)
        for (int j = 1; j <= eulerSize - (1 << i) + 1; ++j) {
            int x = rmq[i - 1][j];
            int y = rmq[i - 1][j + (1 << (i - 1))];
            if (level[x] < level[y]) rmq[i][j] = x;
                else rmq[i][j] = y;
        }
}

int lca(int node1, int node2) {
    int st =_first[node1];
    int dr =_first[node2];
    if (st > dr)
        swap(st, dr);

    int k = lg[dr-st+1];
    int x = rmq[k][st];
    int y = rmq[k][dr - (1 << k) + 1];
    if (level[x] < level[y])
        return x;

    return y;
}

void computeQueries() {
    for (int i = 1; i <= M; ++i) {
        int x, y;
        f >> x >> y;
        g << lca(x, y)<<'\n';
    }
}

int main() {
    readInput();
    dfs(1, 0);
    computeRmq();
    computeQueries();
    return 0;
}