Cod sursa(job #2295837)

Utilizator dragos99Homner Dragos dragos99 Data 3 decembrie 2018 23:06:32
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.55 kb
#include<fstream>
#include<vector>
using namespace std;
    ifstream f("lca.in");
    ofstream g("lca.out");

long n, m;
long prima_aparitie[100005];
long rmq[20][500000];
long log[500000];
vector<long> arbore[140005], euler, nivel;

void dfs(int nod, int inaltime){
    euler.push_back(nod);
    nivel.push_back(inaltime);
    prima_aparitie[nod] = euler.size();

    for(int i = 0 ; i < arbore[nod].size() ; i++){
        dfs(arbore[nod][i], inaltime + 1);

        euler.push_back(nod);
        nivel.push_back(inaltime);
    }
}

void RMQ(){
    long euler_size = euler.size();
    for(long i = 0 ; i < euler_size ; i++){
        rmq[0][i] = euler[i] ;
    }

    for(long i = 1 ; (1<<i) <= euler_size ; i++)
        for(long j = 0 ; j <= euler_size - (1<<(i - 1)) ; j++){
            rmq[i][j] = min( rmq[i-1][j], rmq[i-1][j + (1<<(i-1))] );
        }
}

void calcLG(){
    long euler_size = euler.size();
    for(long i = 2 ; i <= euler_size ; i++)
        log[i] = log[i/2] + 1;
}

long LCA (long x, long y){
    long x_aparitie = prima_aparitie[x];
    long y_aparitie = prima_aparitie[y];

    if(x_aparitie > y_aparitie)
        swap(x_aparitie, y_aparitie);
    long k = log[y_aparitie - x_aparitie + 1];
    return min(rmq[k][x_aparitie-1], rmq[k][y_aparitie - (1<<k) ]);
}

int main()
{
long x, y;
f>>n>>m;
for (long i = 2 ; i <= n ; i++){
    f>>x;
    arbore[x].push_back(i);
}

dfs(1, 0);

RMQ();

calcLG();

for(long i = 0 ; i < m ; i++){
    f>>x>>y;
    g<<LCA(x, y)<<'\n';
}

return 0;
}