Cod sursa(job #2115926)

Utilizator IsacLucianIsac Lucian IsacLucian Data 27 ianuarie 2018 11:25:03
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include <bits/stdc++.h>

using namespace std;

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

int rmq[22][400003];
int E[400003],k;
int niv[400003],poz[100003];
int a[100003],n;
int p[100003];
vector<int>L[100003];

void Euler(int nod,int nivel)
{
    E[++k]=nod;
    niv[k]=nivel;
    poz[nod]=k;

    for(auto i:L[nod])
    {
        Euler(i,nivel+1);
        E[++k]=nod;
        niv[k]=nivel;
    }
}

int main()
{
    int i,j,q,x,y,N;

    fin>>n>>q;
    for(int i=2;i<=n;i++)
    {
        fin>>x;
        L[x].push_back(i);
    }

    Euler(1,1);


    /// p - construire
    p[1]=0;
    for(i=2;i<=k;i++)
        p[i]=1+p[i/2];


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

    N=p[k];
    for(i=1;i<=N;i++)
        for(j=1;j<=k-(1<<i)+1;j++)
        {
            x=niv[rmq[i-1][j]];
            y=niv[rmq[i-1][j+(1<<(i-1))]];

            if(x<y)rmq[i][j]=rmq[i-1][j];
            else rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
        }

    ///interogari
    while(q--)
    {
        fin>>x>>y;
        x=poz[x];
        y=poz[y];
        if(x>y)swap(x,y);

        N=p[y-x+1];
        i=rmq[N][x];
        j=rmq[N][y-(1<<N)+1];

        if(niv[i]<niv[j])fout<<E[i]<<"\n";
        else fout<<E[j]<<"\n";
    }
    return 0;
}