Cod sursa(job #1971015)

Utilizator mariapascuMaria Pascu mariapascu Data 19 aprilie 2017 19:22:12
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb
#include <fstream>
#include <vector>
using namespace std;

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

const int NMax = 100004;

int n, m, nr;
vector<int> G[NMax];
int E[2 * NMax], niv[2 * NMax], pos[NMax], log2[2 * NMax], r[2 * NMax][20];

void Read();
void DFS(int x, int nv);
void Log();
void RMQ();
void Ans();
int LCA(int x, int y);

int main() {
    Read();
    DFS(1, 1);
    RMQ();
    Log();
    Ans();
    fin.close();
    fout.close();
    return 0;
}

void Ans() {
    int x, y;
    for (int i = 1; i <= m; i++) {
        fin >> x >> y;
        fout << LCA(x, y) << '\n';
    }
}

int LCA(int x, int y) {
    x = pos[x]; y = pos[y];
    if (x > y) {
        int aux = x;
        x = y;
        y = aux;
    }
    int k = log2[y - x + 1];
    if (niv[r[x][k]] < niv[r[y - (1 << k) + 1][k]])
        return E[r[x][k]];
    return E[r[y - (1 << k) + 1][k]];
}

void RMQ() {
    int N = 2 * n - 1;
    for (int i = 1; i <= N; i++) r[i][0] = i;
    for (int j = 1; (1 << j) <= N; j++)
        for (int i = 1; i + (1 << j) - 1 <= N; i++)
            if (niv[r[i][j - 1]] < niv[r[i + (1 << (j - 1))][j - 1]])
                r[i][j] = r[i][j - 1];
            else r[i][j] = r[i + (1 << (j - 1))][j - 1];
}

void DFS(int x, int nv) {
    nr++;
    E[nr] = x; niv[nr] = nv; pos[x] = nr;
    for (const auto & y : G[x]) {
        DFS(y, nv + 1);
        nr++;
        E[nr] = x; niv[nr] = nv;
    }
}

void Log() {
    for (int i = 2; i < 2 * NMax; i++)
        log2[i] = log2[i / 2] + 1;
}

void Read() {
    fin >> n >> m;
    int x;
    for (int i = 2; i <= n; i++) {
        fin >> x;
        G[x].push_back(i);
    }
}