Cod sursa(job #2124401)

Utilizator albucristianAlbu Cristian-Gabriel albucristian Data 7 februarie 2018 10:48:07
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.8 kb
#include <fstream>
#include <vector>

#define MAXN 100005
#define inf 0x3f3f3f3f

using namespace std;

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

vector <int> graph[MAXN];
int nn, n, m;
int fr[MAXN], niv[MAXN];
int log[MAXN], lin, mm;

struct str{
    int val, poz;
};

str rmq[22][4000001];

inline void DFS(int nod, int parinte) {
    rmq[0][++nn] = {niv[nod], nod};

    if (!fr[nod])
        fr[nod] = nn;

    for (auto x : graph[nod]) {
        if (x != parinte) {
            niv[x] = niv[nod] + 1;
            DFS(x, nod);
        }
       // rmq[0][++nn] = {niv[nod], nod};
    }
    rmq[0][++nn] = {niv[parinte], parinte};
}

inline void RMQ() {
    mm = log[nn];

    for (int i = 1; i <= mm; i++) {
        for (int j = 1; (j + (1 << (i - 1))) <= nn; j++) {
            if (rmq[i - 1][j].val < rmq[i - 1][j + (1 << (i - 1))].val)
                rmq[i][j] = rmq[i - 1][j];
            else
                rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
        }
    }
}

inline int Query(int a, int b) {
   // fout << fr[a] << " " << fr[b];
    lin = log[b - a + 1];

    if (rmq[lin][a].val < rmq[lin][b - (1 << lin) + 1].val)
        return rmq[lin][a].poz;
    else
        return rmq[lin][b - (1 << lin) + 1].poz;

}

inline void Read() {
    int x;

    fin >> n >> m;

    for (int i = 2; i <= n; i++) {
        fin >> x;

        graph[x].push_back(i);
        graph[i].push_back(x);
    }

    niv[1] = 1;

    DFS(1, 1);

    for (int i = 2; i <= nn; i++)
        log[i] = log[i / 2] + 1;

    RMQ();

    int y;

    for (int i = 1; i <= m; i++) {
        fin >> x >> y;

        fout << Query(min(fr[x], fr[y]), max(fr[x], fr[y])) << "\n";
    }
}

int main () {
    Read();

    fin.close(); fout.close(); return 0;
}