Cod sursa(job #1365611)

Utilizator somuBanil Ardej somu Data 28 februarie 2015 13:42:47
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.78 kb
#include <iostream>
#include <fstream>
#include <vector>
#define nmax 100005

using namespace std;

int n, m;
bool viz[nmax];
int Euler[2*nmax], Exp[2*nmax], Min[19][2*nmax], Poz[19][2*nmax], Nivel[nmax], P[nmax];
vector <int> G[nmax];

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

void preprocess() {
    
    Exp[1] = 0;
    for (int i = 2; i <= Euler[0]; i++)
        Exp[i] = Exp[i/2] + 1;
    
    for (int i = 1; i <= Euler[0]; i++) {
        Min[0][i] = Nivel[Euler[i]];
        Poz[0][i] = i;
    }
        
    
    for (int i = 1; i <= Exp[Euler[0]]; i++)
        for (int j = 1; j <= Euler[0] - (1<<i) + 1; j++) {
            int st = j;
            int dr = st + (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];
        }
    
}

int main() {
    
    ifstream fin("lca.in");
    ofstream fout("lca.out");
    
    fin >> n >> m;
    for (int i = 2; i <= n; i++) {
        int x;
        fin >> x;
        G[x].push_back(i);
    }
    
    euler(1, 1);
    
    preprocess();
    
    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 = Euler[Poz[k][x]];
        x = y - (1<<k) + 1;
        if (rez > Min[k][x])
            lca = Euler[Poz[k][x]];
        fout << lca << "\n";
    }
    
    fin.close();
    fout.close();
    
    return 0;
}