Cod sursa(job #2387129)

Utilizator CodrinsahCotarlan Codrin Codrinsah Data 24 martie 2019 12:49:27
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.55 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fi ("lca.in");
ofstream fo ("lca.out");
vector<int> v[100005];
int nrnod,nrq,lg,eul[200006],nivel[100006],firstap[100006],rmq[20][200006];
void dfs(int nod,int lvl)
{
    nivel[nod]=lvl;
    for (int i=0;i<v[nod].size();i++)
    {
        int nextnod=v[nod][i];
        lg++;
        eul[lg]=nod;
        dfs(nextnod,lvl+1);
    }
    lg++;
    eul[lg]=nod;
}
void precalc()
{
    for (int i=1;i<=lg;i++) rmq[0][i]=eul[i];
    for (int lvl=1;(1<<lvl)<=lg;lvl++)
        for (int i=1;i+(1<<lvl)-1<=lg;i++)
    {
        int nod1=rmq[lvl-1][i];
        int nod2=rmq[lvl-1][i+(1<<(lvl-1))];
        if (nivel[nod1]<=nivel[nod2]) rmq[lvl][i]=nod1;
        else rmq[lvl][i]=nod2;
    }
}
int querry(int nod1,int nod2)
{
    int power=0,poz1,poz2;
    poz1=firstap[nod1];
    poz2=firstap[nod2];
    if (poz1>poz2) swap (poz1,poz2);
    int dif=poz2-poz1+1;
    while (dif) {dif=dif/2;power++;}
    power--;
    nod1=rmq[power][poz1];
    nod2=rmq[power][poz2-(1<<power)+1];
    if (nivel[nod1]<nivel[nod2]) return nod1;
    else return nod2;
}
int main()
{
    fi>>nrnod>>nrq;
    for (int x=2;x<=nrnod;x++)
    {
        int y;
        fi>>y;
        v[y].push_back(x);
    }
    dfs(1,0);
    for (int i=1;i<=lg;i++)
        if (firstap[eul[i]]==0) firstap[eul[i]]=i;
 //   for (int i=1;i<=lg;i++) fo<<eul[i]<<' ';
    precalc();
    for (int i=1;i<=nrq;i++)
    {
        int x,y;
        fi>>x>>y;
        fo<<querry(x,y)<<'\n';
    }
    return 0;
}