Cod sursa(job #2510593)

Utilizator Rares31100Popa Rares Rares31100 Data 16 decembrie 2019 22:02:24
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.71 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,en;
int vf[200001],urm[200001],last[100001],nr;

pair<int,int> eul[200001];
int interv[100001],nr2;

int rmq[20][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;

    interv[nod]=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]=nr2;
        }
}

int main()
{
    cin>>n>>m;

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

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

    eul_dfs(1,0);

    en=n*2-1;

    for(int i=1;i<=en;i++)
        rmq[1][i]=i;

    for(int k=2,r=2;k<=en;k*=2,r++)
        for(int i=1;i+k-1<=en;i++)
        {
            int p1=rmq[r-1][i];
            int p2=rmq[r-1][i+k/2];

            if(eul[p1].S<eul[p2].S)
                rmq[r][i]=p1;
            else
                rmq[r][i]=p2;
        }

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

        int a=interv[i];
        int b=interv[j];

        if(a>b)
            swap(a,b);

        int m=pow( 2 , (int)log2(b-a+1) );

        int p1=rmq[ (int)log2(m)+1 ][ a ];
        int p2=rmq[ (int)log2(m)+1 ][ b-m+1 ];

        if(eul[p1].S<eul[p2].S)
            cout<<eul[p1].F<<'\n';
        else
            cout<<eul[p2].F<<'\n';
    }

    return 0;
}