Cod sursa(job #1921592)

Utilizator caprariuapCaprariu Alin-Paul caprariuap Data 10 martie 2017 13:23:55
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.72 kb
#include <fstream>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;

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

vector <int> v[100010];
int PE[200100],nivel[100010],ind[100010],n,m,i,j,k,nr,rmq[200100][20],LOGARITMINBAZA2[200100],doi[20];

void euler(int x)
{
    PE[++nr]=x;
    ind[x]=nr;
    for (int i=0; i<v[x].size(); i++)
        {
            nivel[v[x][i]]=nivel[x]+1;
            euler(v[x][i]);
            PE[++nr]=x;
        }
}

int main()
{
    fin >> n >> m;
    for (i=2; i<=n; i++)
    {
        int x;
        fin >> x;
        v[x].push_back(i);
    }
    nr=0;
    euler(1);
    LOGARITMINBAZA2[1]=0;
    for (i=2; i<=nr; i++)
        LOGARITMINBAZA2[i]=LOGARITMINBAZA2[i/2]+1;
    doi[0]=1;
    for (i=1; doi[i-1]<=nr; i++)
        doi[i]=2*doi[i-1];
    for (i=1; i<=nr; i++)
        rmq[i][0]=PE[i];
    for (int k=1; k<=LOGARITMINBAZA2[nr]; k++)
    {
        for (i=1; i<=nr; i++)
            if (nivel[rmq[i][k-1]]<nivel[rmq[min(i+doi[k-1],nr)][k-1]])
            rmq[i][k]=rmq[i][k-1];
        else
            rmq[i][k]=rmq[min(i+doi[k-1],nr)][k-1];
    }
    for (i=1; i<=m; i++)
    {
        int a,b;
        fin >> a >> b;
        a=ind[a];
        b=ind[b];
        if (a>b)
            swap(a,b);
        int d=LOGARITMINBAZA2[b-a+1];
        if (nivel[rmq[a][d]]<nivel[rmq[b-doi[d]+1][d]])
            fout << rmq[a][d] << '\n';
        else
            fout << rmq[b-doi[d]+1][d] << '\n';
    }
//    for (i=0; i<=LOGARITMINBAZA2[nr]; i++)
//    {
//        for (j=1; j<=nr; j++)
//            fout << rmq[j][i] << ' ';
//        fout << '\n';
//    }
//    for (i=1; i<=5; i++)
//        fout << PE[i] << ' ';
}