Cod sursa(job #1808104)

Utilizator Chirita_MateiChirita Matei Chirita_Matei Data 17 noiembrie 2016 12:44:45
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <fstream>
#include <vector>
#include <cmath>

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

vector <int> v[100005];

int pe[200010],k,n,m,x,niv,ni[200010],in[100005],p[100005][19],p1[100005][19],y,a,b,l,d;

void euler(int x)
{
    for(int i=0;i<v[x].size();i++)
    {
        pe[++k]=x;

        if(in[x]==0)
        {
            in[x]=k;
        }

        ni[k]=niv;
        niv++;
        euler(v[x][i]);
        niv--;
    }

    pe[++k]=x;

    if(in[x]==0)
    {
        in[x]=k;
    }

    ni[k]=niv;
}

void rmq()
{
    for(int i=0;i<=(int)log2(k);++i)
    {
        for(int j=1;j<=k;j++)
        {
            if(i==0)
            {
                p[j][i]=ni[j];
                p1[j][i]=pe[j];
            }

            else if(j+(1<<(i-1))<=k){
                p[j][i]=min(p[j][i-1],p[j+(1<<(i-1))][i-1]);

                if(p[j][i-1]>=p[j+(1<<(i-1))][i-1])
                {
                    p1[j][i]=p1[j+(1<<(i-1))][i-1];
                }

                else
                {
                    p1[j][i]=p1[j][i-1];
                }
            }

            else break;
        }
    }
}

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

    for(int i=1;i<=n-1;i++)
    {
        fin>>x;
        v[x].push_back(i+1);
    }

    euler(1);
    rmq();

    for(int i=1;i<=m;i++)
    {
        fin>>x>>y;

        a=in[x];
        b=in[y];

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

        d=b-a+1;
        l=(int)log2(d);


        if(p[a][l]>=p[b-(1<<l)+1][l])
        {
            fout<<p1[b-(1<<l)+1][l]<<'\n';
        }

        else
        {
            fout<<p1[a][l]<<'\n';
        }
    }

    return 0;
}