Cod sursa(job #2565408)

Utilizator DanutAldeaDanut Aldea DanutAldea Data 2 martie 2020 14:10:18
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.9 kb
#include <fstream>
#include <iostream>
#include <vector>
#define dim 100010
using namespace std;

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

int N[2*dim],F[dim],E[dim],k,lg[dim],rmq[20][2*dim],e,lung;
int n,m,i,j;
vector <int> l[dim];

void dfs(int nod,int niv){
    F[nod]=++k; ///prima ap a lui nod
    E[k]=nod; ///nodul in parcurgerea euler
    N[k]=niv; ///niv nodului de pe poz k in parcurgerea euler

    for(int i=0; i<l[nod].size(); i++){
        dfs(l[nod][i],niv+1);
        E[++k]=nod;
        N[k]=niv;
    }
}

int main(){
    fin>>n>>m;
    for(i=2;i<=n;i++){
        fin>>j;
        l[j].push_back(i);
    }

    dfs(1,0);

//    for(i=1;i<=k;i++)
//        cout<<E[i]<<" ";
//    cout<<"\n";
//    for(i=1;i<=k;i++)
//        cout<<N[i]<<" ";
//    cout<<"\n\n";
//
//    for(i=1;i<=n;i++)
//        cout<<F[i]<<" ";

    for(i=2;i<=k;i++)
        lg[i]=lg[i/2]+1;

    for(i=1;i<=k;i++)
        rmq[0][i]=i;

    for(e=1, lung=1; e<=lg[n]+1; e++, lung*=2){

        for(i=1;i<=k;i++){
            rmq[e][i]=rmq[e-1][i];

            if(i+lung<=k)
                if(N[rmq[e][i]] > N[rmq[e-1][i+lung]])
                    rmq[e][i]=rmq[e-1][i+lung];
        }

    }

//    cout<<"\n\n";
//    for(e=0;e<=lg[n];e++,cout<<"\n")
//        for(i=1;i<=k;i++)
//            cout<<rmq[e][i]<<" ";

    for(;m;m--){
        fin>>i>>j;

        i=F[i]; j=F[j];
        if(j<i)
            swap(i,j);

//        cout<<i<<" "<<j<<" ";

        lung=j-i+1;
//        cout<<lung<<" ";
        e=lg[lung];

//        cout<<"e="<<e<<"\n";
//
//        cout<<E[rmq[e][i]]<<" "<<E[rmq[e][j-lung+1]]<<"\n\n";

//        fout<<min(rmq[e][i],rmq[e][j-lung+1])<<"\n";
        if(N[rmq[e][i]]<N[rmq[e][j-lung+1]]){
            fout<<E[rmq[e][i]]<<"\n";
        }else{
            fout<<E[rmq[e][j-lung+1]]<<"\n";
        }
    }

    return 0;
}