Cod sursa(job #1320817)

Utilizator somuBanil Ardej somu Data 18 ianuarie 2015 16:00:33
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.89 kb
#include <iostream>
#include <fstream>
#include <vector>
#define nmax 100005
#define inf 1<<30

using namespace std;

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

int n, m;
int k = 0;
int T[nmax], E[2*nmax], Min[20][2*nmax], Nivel[nmax], Poz[20][2*nmax], Exp[2*nmax], P[nmax];
vector <int> node[nmax];
bool viz[nmax];

void citire() {
    fin >> n >> m;
    for (int i = 1; i < n; i++) {
        fin >> T[i+1];
        node[T[i+1]].push_back(i+1);
    }
}

void euler(int nod, int niv) {
    E[++E[0]] = nod;
    Nivel[nod] = niv;
    P[nod] = E[0];
    for (int i = 0; i < node[nod].size(); i++){
            euler(node[nod][i], niv + 1);
            E[++E[0]] = nod;
    }
}

void preprocesare() {
    for (int i = 1; i <= E[0]; i++)
        Min[0][i] = Nivel[E[i]],
        Poz[0][i] = i;
    for (int i = 1; i <= 18; i++)
        for (int j = 1; j <= (E[0] - (1<<i) + 1); j++) {
            int st = j;
            int dr = j + (1<<i) - 1;
            int mid = dr - (1<<(i-1)) + 1;
            Min[i][j] = Min[i-1][st];
            Poz[i][j] = Poz[i-1][st];
            if (Min[i][j] > Min[i-1][mid])
                Min[i][j] = Min[i-1][mid],
                Poz[i][j] = Poz[i-1][mid];
        }
}

void solve() {
    euler(1, 1);
    preprocesare();
    Exp[1] = 0;
    
    for (int i = 2; i <= E[0]; i++)
        Exp[i] = Exp[i/2] + 1;
    
    for (int i = 1; i <= m; i++) {
        int x, y;
        fin >> x >> y;
        x = P[x], y = P[y];
        if (x > y) swap(x, y);
        
        int l = y - x + 1;
        int k = Exp[l];
        
        int rez = Min[k][x];
        int lca = E[ Poz[k][x] ];
        
        x = y - (1<<k) + 1;
        
        if (rez > Min[k][x]) {
            rez = Min[k][x];
            lca = E[ Poz[k][x] ];
        }
        
        fout << lca << "\n";
        
    }
    
}

int main() {
    
    citire();
    solve();
    
    fin.close();
    fout.close();
    
    return 0;
}