Cod sursa(job #2510769)

Utilizator Rares31100Popa Rares Rares31100 Data 17 decembrie 2019 12:41:00
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.69 kb
#include <fstream>
#include <cmath>
#define Niv second
#define Nod first
#define Size 100000

using namespace std;

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

int n,neul,q,vf[Size*2+1],urm[Size*2+1],last[Size+1];
pair <int,int> eul[Size*2];
int pozitie[Size+1];
int nr;

int rmq[20][Size*2];

void adauga(int from,int to)
{
    vf[++nr]=to;
    urm[nr]=last[from];
    last[from]=nr;
}

void dfseu(int nod,int from,int nivel)
{
    eul[++nr].Nod=nod;
    eul[nr].Niv=nivel;
    pozitie[nod]=nr;
    
    for(int k=last[nod];k;k=urm[k])
        if(from!=vf[k])
        {
            dfseu(vf[k],nod,nivel+1);
            
            eul[++nr].Nod=nod;
            eul[nr].Niv=nivel;
        }
}

int main()
{
    cin>>n>>q;
    
    nr=0;
    for(int tata,i=2;i<=n;i++)
    {
        cin>>tata;
        
        adauga(tata,i);
        adauga(i,tata);
    }
    
    nr=0;
    dfseu(1,0,0);
    
    neul=n*2-1;
    
    for(int i=1;i<=neul;i++)
        rmq[1][i]=i;
        
    for(int r=2,k=2;k<=neul;r++,k*=2)
        for(int i=1;i<=neul-k+1;i++)
            if(eul[ rmq[r-1][i] ].Niv<eul[ rmq[r-1][i+k/2] ].Niv)
                rmq[r][i]=rmq[r-1][i];
            else
                rmq[r][i]=rmq[r-1][i+k/2];
                
    for(int sol,nod1,nod2,a,b,i=1;i<=q;i++)
    {
        cin>>nod1>>nod2;
        
        a=pozitie[nod1];
        b=pozitie[nod2];
        
        if(a>b)
            swap(a,b);
            
        int m=pow( 2 , (int)log2(b-a+1) );
        int r=(int)log2(b-a+1)+1;
        
        if(eul[ rmq[r][a] ].Niv<eul[ rmq[r][b-m+1] ].Niv)
            sol=rmq[r][a];
        else
            sol=rmq[r][b-m+1];
            
        cout<<eul[sol].Nod<<'\n';
    }    
    
    return 0;
}