Cod sursa(job #2115931)

Utilizator danyvsDan Castan danyvs Data 27 ianuarie 2018 11:26:20
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.6 kb
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

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

const int NMAX = 100005;
const int MMAX = 4000005;

int n, q;
int rmq[22][MMAX];
int E[MMAX], k;
int lvl[MMAX], pos[NMAX];
vector<int> G[NMAX];
int pw[MMAX];

void euler(int node, int level) {
    E[++ k] = node;
    lvl[k] = level;
    pos[node] = k;
    for (auto it : G[node]) {
        euler(it, level + 1);
        E[++ k] = node;
        lvl[k] = level;
    }
}

int main() {
    fin >> n >> q;
    for (int i = 2; i <= n; ++ i) {
        int temp;
        fin >> temp;
        G[temp].push_back(i);
    }

    euler(1, 1);

    // vectorul de puteri
    pw[1] = 0;
    for (int i = 2; i <= k; ++ i)
        pw[i] = 1 + pw[i / 2];

    //rmq
    for (int i = 1; i <= k; ++ i)
        rmq[0][i] = i;
    int maxpw = pw[k];
    for (int i = 1; i <= maxpw; ++ i)
        for (int j = 1; j <= k - (1 << i) + 1; ++ j) {
            int x = lvl[rmq[i - 1][j]];
            int y = lvl[rmq[i - 1][j + (1 << (i - 1))]];
            if (x < y)
                rmq[i][j] = rmq[i - 1][j];
            else
                rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
        }

    // interogari
    for (int i = 1; i <= q; ++ i) {
        int x, y;
        fin >> x >> y;
        x = pos[x];
        y = pos[y];
        if (x > y)
            swap(x, y);
        int lg = pw[y - x + 1];
        int a = rmq[lg][x];
        int b = rmq[lg][y - (1 << lg) + 1];
        fout << (lvl[a] < lvl[b] ? E[a] : E[b]) << "\n";
    }

    return 0;
}