Cod sursa(job #2360167)

Utilizator marcogoldPop Mihali Marco Silviu marcogold Data 1 martie 2019 13:33:10
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.68 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

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

int n,m,a,N;
vector<int> vecini[100005];
vector<int> ordonatEuler;
vector<int> log2;
int first[100005];
int rmq[25][100005];
int nivel[100005];

void DFS(int nod,int nnivel)
{
    ordonatEuler.push_back(nod);
    nivel[nod]=nnivel;
    for(int vec:vecini[nod])
    {
        DFS(vec,nnivel+1);
        ordonatEuler.push_back(nod);
    }
}

int main()
{

fi>>n>>m;
    for(int i=2; i<=n; i++)
    {
        fi>>a;

        vecini[a].push_back(i);
    }

    DFS(1,0);

    N=ordonatEuler.size()-1;

    log2.push_back(0);
    log2.push_back(0);

    for(int i=2; i<=N; i++)
        log2.push_back(log2[i/2]+1);

    for(int i=0; i<=N; i++)
    {
        rmq[0][i]=ordonatEuler[i];

        if(first[ordonatEuler[i]]==0)
            first[ordonatEuler[i]]=i;
    }



    for(int p=1; p<=log2[N]+1; p++) ///putere de 2
        for(int j=0; j<=N-(1<<p)+1 ; j++) /// elem

            if(nivel[rmq[p-1][j] ]<nivel[ rmq[p-1][j+(1<<(p-1)) ]])
                rmq[p][j]=rmq[p-1][j];
            else
                rmq[p][j]=rmq[p-1][j+(1<<(p-1))];


    for(int i=1; i<=m; i++)
    {

        int nod1,nod2,l,lg;
        fi>>nod1>>nod2;
        nod1=first[nod1]; ///primele poz
        nod2=first[nod2];

        if(nod1>nod2)swap(nod1,nod2);

        l=nod2-nod1+1;
        lg=log2[l];

        if(nivel[rmq[lg][nod1] ]< nivel[ rmq[lg][nod2-(1<<lg)+1 ]] )
            fo<<rmq[lg][nod1]<<'\n';
        else
            fo<<rmq[lg][nod2-(1<<lg)+1]<<'\n';

    }

    fi.close();
    fo.close();
    return 0;
}