Cod sursa(job #2510457)

Utilizator Rares31100Popa Rares Rares31100 Data 16 decembrie 2019 18:56:27
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.88 kb
#include <fstream>
#include <bitset>
#include <cmath>
#define F first
#define S second
#define Max 100001

using namespace std;

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

int n,m,base;
int vf[200001],urm[200001],last[100001],nr;
pair<int,int> eul[540001];
int nr2;

pair <int,int> interv[100001];

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

void eul_dfs(int nod,int no,int niv=0)
{
    eul[++nr2].F=nod;
    eul[nr2].S=niv;

    if(!interv[nod].F)
        interv[nod].F=nr2;

    interv[nod].S=nr2;

    for(int nod2=last[nod];nod2;nod2=urm[nod2])
        if(vf[nod2]!=no)
        {
            eul_dfs(vf[nod2],nod,niv+1);

            eul[++nr2].F=nod;
            eul[nr2].S=niv;

            interv[nod].S=nr2;
        }
}

int lca(int a,int b)
{
    pair <int,int> minn={0,Max};

    while(a<=b)
    {
        if(a%2==1)
        {
            if(minn.S>eul[a].S)
                minn=eul[a];
            a++;
        }

        if(b%2==0)
        {
            if(minn.S>eul[b].S)
                minn=eul[b];
            b--;
        }

        a/=2;b/=2;
    }

    return minn.F;
}

int main()
{
    cin>>n>>m;
    base=pow( 2 , (int)log2(n*2-1)+(log2(n*2-1)>(int)log2(n*2-1)?1:0) );
    nr2=base-1;

    for(int tat,i=2;i<=n;i++)
    {
        cin>>tat;

        adauga(tat,i);
        adauga(i,tat);
    }

    eul_dfs(1,0);

    for(int i=base/2;i;i/=2)
        for(int j=i;j<=i*2-1;j++)
            if(eul[j*2].S<eul[j*2+1].S)
                eul[j]=eul[j*2];
            else
                eul[j]=eul[j*2+1];

    for(int i,j,k=1;k<=m;k++)
    {
        cin>>i>>j;

        if(interv[i].F<interv[j].S)
            cout<<lca(interv[i].F,interv[j].S)<<'\n';
        else
            cout<<lca(interv[j].F,interv[i].S)<<'\n';
    }

    return 0;
}