Cod sursa(job #2533608)

Utilizator nicolaefilatNicolae Filat nicolaefilat Data 29 ianuarie 2020 14:28:34
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.96 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <cmath>

const int MAXN = 100000 * 2 + 1;
const int MAXLOG = 18;

using namespace std;

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

vector<int>graf[MAXN];
struct punct{
    int nod,h;


};
int n,euler[MAXN],index,inaltime[MAXN],pozitie[MAXN];
int lg[MAXN],pow2[MAXLOG];
punct dp[MAXLOG][MAXN];

void dfs(int nod,int anterior = -1){
    euler[++index] = nod;
    for(auto vecin : graf[nod]){
        if(vecin != anterior){
            inaltime[vecin] = inaltime[nod] + 1;
            dfs(vecin,nod);
            euler[++index] = nod;
        }
    }
}
punct min(punct a,punct b){
    if(a.h < b.h)
        return a;
    return b;
}

int main()
{
    int intrebari;
    in>>n>>intrebari;

    for(int i = 2; i <= n; i++){
        int tata;
        in>>tata;
        graf[i].push_back(tata);
        graf[tata].push_back(i);
    }
    inaltime[1] = 1;
    dfs(1);
    for(int i = 1; i <= index; i++){
        dp[0][i] = punct{euler[i],inaltime[euler[i]]};
        if(!pozitie[euler[i]])
            pozitie[euler[i]] = i;
    }
    for(int put = 1; put <= MAXLOG - 1; put++){
        for(int i = 1; i <= index; i++){
            /// i + 2 ^ put = [i,i + 2 ^ (put - 1)] + [i + 2^(put-1) + 2^(put - 1),i + 2^put]
            dp[put][i] = min(dp[put - 1][i],dp[put - 1][i + (1<<(put - 1))]);
        }
    }
    lg[1] = 0;
    for(int i = 2; i < MAXN; i++){
        lg[i] = lg[i / 2] + 1;
    }
    pow2[1] = 2;
    for(int i = 2; i < MAXLOG; i++){
        pow2[i] = pow2[i - 1] * 2;
    }
    for(int i = 1; i <= intrebari; i++){
        int x,y;
        in>>x>>y;
        int pozx = pozitie[x],pozy = pozitie[y];
        if(pozx > pozy)
            swap(pozx,pozy);
        int lung = pozy - pozx;
        int log_lung = lg[lung];
        out<<min(dp[log_lung][pozx],dp[log_lung][pozy - pow2[log_lung]]).nod<<"\n";
    }

    return 0;
}