Cod sursa(job #2492407)

Utilizator mirceaisherebina mircea mirceaishere Data 14 noiembrie 2019 18:15:27
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.39 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

long int n, m, i, j, k, x, v[18][200002], lg[200002], euler[200002], niv[200002], poz[200002], st, dr, s, d, l;
vector <int> a[200002];

void dfs(int nod, int nivel){
    k++;
    niv[k]=nivel;
    euler[k]=nod;
    poz[nod]=k;
    for(int i=0; i<a[nod].size(); i++){
        dfs(a[nod][i], nivel+1);
        k++;
        niv[k]=nivel;
        euler[k]=nod;
    }

}


int main () {
    fin>>n>>m;
    for(i=2; i<=n; i++){
        fin>>x;
        a[x].push_back(i);
    }
    dfs(1, 1);
    for(i=2; i<=k; i++){
        lg[i]=lg[i/2]+1;
    }
    ///lg e cea mai mare putere a lui 2 mai mica decat i
    for(i=1; i<=k; i++){
        v[0][i]=i;
    }
    for(i=1; (1<<i)<=k; i++){
        for(j=1; j<=k-(1<<i)+1; j++){
            l=1<<(i-1);
            v[i][j]=v[i-1][j];
            if(niv[ v[i][j] ]>niv[ v[i-1][j+l] ]){
                v[i][j]=v[i-1][j+l];
            }
        }
    }
    for(i=1; i<=m; i++){
        fin>>st>>dr;
        st=poz[st];
        dr=poz[dr];
        if(st>dr){
            swap(st, dr);
        }
        d=dr-st+1;
        l=lg[d];
        s=dr-(1<<l)+1;
        if(niv[ v[l][st] ] < niv[ v[l][s] ]){
            fout<<euler[ v[l][st] ]<<"\n";
        }else{
            fout<<euler[ v[l][s] ]<<"\n";
        }
    }
}