Cod sursa(job #1464837)

Utilizator CollermanAndrei Amariei Collerman Data 25 iulie 2015 13:39:49
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.53 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <bitset>
using namespace std;
ofstream fout("lca.out");
ifstream fin("lca.in");
const int NMAX = 100005;

int n, m, lg;
int Euler[NMAX * 2], Nivel[NMAX * 2], Poz[NMAX];
int ST[NMAX][20];
bitset<NMAX> Viz;
vector<int> Arbore[NMAX];

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

void parcurgere_euler(int nod, int nivel)
{
    Euler[++lg] = nod;
    Nivel[lg] = nivel;
    Poz[nod] = lg;
    Viz[nod] = true;

    for(auto x : Arbore[nod]) {
        if(!Viz[x])
            parcurgere_euler(x, nivel + 1);
        Euler[++lg] = nod;
        Nivel[lg] = nivel;
    }
}

void rmq()
{
    for(int i=1; i<=lg; i++) ST[i][0] = i;

    for(int j=1; (1<<j)<=lg; j++) {
        for(int i=1; i+(1<<j)-1<=lg; i++) {
            if(Nivel[ST[i][j-1]] < Nivel[ST[i+(1<<(j-1))][j-1]])
                ST[i][j] = ST[i][j-1];
            else
                ST[i][j] = ST[i+(1<<(j-1))][j-1];
        }
    }
}

void lca(int x, int y)
{
    int a, b, k;

    a = Poz[x], b = Poz[y];
    if(a > b) swap(a, b);
    k = log2(b - a + 1);

    if(Nivel[ST[a][k]] <= Nivel[ST[b-(1<<k)+1][k]])
        fout << Euler[ST[a][k]] << '\n';
    else
        fout << Euler[ST[b-(1<<k)+1][k]] << '\n';
}

int main()
{
    citire();
    parcurgere_euler(1, 0);
    rmq();

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

    return 0;
}