Cod sursa(job #2533604)

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

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

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];
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);
//    cout<<"Parcurgere Euler : ";
//    for(int i = 1; i <= index; i++)
//        cout<<i<<" ";
//    cout<<endl;
//    cout<<"Parcurgere Euler : ";
//    for(int i = 1; i <= index; i++)
//        cout<<euler[i]<<"  ";
//    cout<<endl;
//    cout<<"Inaltime nod     : ";
//    for(int i = 1; i <= index; i++)
//        cout<<inaltime[euler[i]]<<"  ";
//    cout<<endl;
    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))]);
        }
    }
    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 = log2(lung);

        out<<min(dp[log_lung][pozx],dp[log_lung][pozy - (1<<log_lung)]).nod<<"\n";
    }

    return 0;
}