Cod sursa(job #2605560)

Utilizator AndreeaGherghescuAndreea Gherghescu AndreeaGherghescu Data 25 aprilie 2020 14:00:49
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.65 kb
#include <iostream>
#include <fstream>

using namespace std;

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

const int N=100002;

int t[N],lst[N],vf[N],urm[N],nr,log2[2*N];
int ne,nivel[N],prima[N],e[2*N],rmq[18][2*N];

void adauga (int x, int y)
{
    vf[++nr]=y;
    urm[nr]=lst[x];
    lst[x]=nr;
}
void euler (int nod)
{
    e[++ne]=nod;
    nivel[nod]=1+nivel[t[nod]];
    prima[nod]=ne;
    for (int p=lst[nod];p!=0;p=urm[p])
    {
        int y=vf[p];
        if (prima[y]==0)
        {
            euler (y);
            e[++ne]=nod;
        }
    }
}

void log (int n)
{
    log2[1]=0;
    for (int i=2;i<=2*n-1;i++)
    {
        log2[i]=log2[i/2]+1;
    }
}
int lca (int x, int y)
{
    int p=prima[x];
    int q=prima[y];
    if (p>q) swap(p,q);

    int l=log2[q-p+1];

    int st=rmq[l][p+(1<<l)-1];
    int dr=rmq[l][q];

    if (nivel[e[st]]<=nivel[e[dr]])
        return e[st];
    return e[dr];
}
int main()
{
    int n,m,x,y;
    in>>n>>m;
    for (int i=2;i<=n;i++)
    {
        in>>x;
        adauga (x,i);
        t[i]=x;
    }
    log(n);
    euler (1);

    for (int i=1;i<=2*n-1;i++)
        rmq[0][i]=i;

    for (int i=1;(1<<i)<=2*n-1;i++)
    {
        for (int j=1<<i;j<=2*n-1;j++)
        {
            int st,dr;
            st=rmq[i-1][j-(1<<(i-1))];
            dr=rmq[i-1][j];
            if (nivel[e[st]]>nivel[e[dr]])
                rmq[i][j]=dr;
            else rmq[i][j]=st;
            //out<<rmq[i][j]<<' ';
        }
        //out<<'\n';
    }

    for (int i=1;i<=m;i++)
    {
        in>>x>>y;
        out<<lca (x,y)<<'\n';
    }
    return 0;
}