Cod sursa(job #1363761)

Utilizator mucenic_b101Bogdan Mucenic mucenic_b101 Data 27 februarie 2015 11:02:32
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.75 kb
#include <fstream>
#include <vector>
#define MAXN 100000
#define LOG 21
using namespace std;

typedef vector <int> graf;
graf Arb[MAXN + 1];
int E[(2 * MAXN) + 1], L[(2 * MAXN) + 1], Ind[MAXN + 1];
int RMQ[LOG + 1][MAXN + 1];
int lg[(2 * MAXN) + 1];
int nrn = 0;

int minim(int x, int y) {
    return (x < y ? x : y);
}

int maxim(int x, int y) {
    return (x > y ? x : y);
}

void EULER(int node, int lvl) {
    E[nrn] = node;
    if (Ind[node] == -1)
        Ind[node] = nrn;

    L[nrn++] = lvl;
    for (graf :: iterator it = Arb[node].begin() ; it != Arb[node].end() ; ++it) {
        EULER(*it, lvl + 1);
        E[nrn] = node;
        L[nrn++] = lvl;
    }
}

int query(int x, int y) {
    int diff = y - x + 1, l = lg[diff];
    int sol = RMQ[l][x];
    int df = diff - (1 << l);
    if (L[sol] > L[RMQ[l][x + df]])
        sol = RMQ[l][x + df];

    return E[sol];
}

int main () {
    ifstream cin("lca.in");
    ofstream cout("lca.out");

    int n, m;
    cin >> n >> m;
    for (int i = 2 ; i <= n ; ++i) {
        int d;
        cin >> d;
        Arb[d].push_back(i);
    }
    
    for (int i = 1 ; i <= n ; ++i)
        Ind[i] = -1;

    EULER(1, 0);

    lg[1] = 0;
    for (int i = 2 ; i <= nrn ; ++i)
        lg[i] = 1 + lg[i / 2];

    for (int i = 0 ; i < nrn ; ++i)
        RMQ[0][i] = i;

    for (int j = 1 ; j <= lg[nrn] ; ++j)
        for (int i = 0 ; (i + (1 << j) - 1) < nrn ; ++i) {
            if (L[RMQ[j - 1][i]] < L[RMQ[j - 1][i + (1 << (j - 1))]])
                RMQ[j][i] = RMQ[j - 1][i];
            else
                RMQ[j][i] = RMQ[j - 1][i + (1 << (j - 1))];
        }

    for (int i = 0 ; i < m ; ++i) {
        int x, y;
        cin >> x >> y;
        cout << query(minim(Ind[x], Ind[y]), maxim(Ind[x], Ind[y])) << "\n";
    }

    return 0;
}