Cod sursa(job #2136600)

Utilizator NannyiMaslinca Alecsandru Mihai Nannyi Data 20 februarie 2018 00:16:11
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.82 kb
#include <fstream>
#include <vector>
#include <iostream>
using namespace std;
#define nmax 100005
ifstream f("lca.in");
ofstream g("lca.out");

vector<int>Q[nmax];
vector<pair<int,int>>query;

int n,m,ncurent,primaaparitie[nmax*2+10],niv[nmax],euler[nmax*2+10],tata[nmax],loga[nmax];
int dp[nmax][20];

void read()
{
    f>>n>>m;
    for (int i=2; i<=n; ++i)
    {
        int a;
        f>>a;
        Q[a].push_back(i);
        tata[i]=a;
    }
    for (int i=1; i<=m; ++i)
    {
        int a,b;
        f>>a>>b;
        query.push_back({a,b});
    }
}

void dfs(int nod)
{
    euler[++ncurent]=nod;
    if (!primaaparitie[nod])
        primaaparitie[nod]=ncurent;
    for (auto w:Q[nod])
    {
        niv[w]=niv[tata[w]]+1;
        dfs(w);
    }
    if (nod!=1)
        euler[++ncurent]=tata[nod];
}

void logga()
{
    for (int i=2; i<=nmax; ++i)
        loga[i]=loga[i/2]+1;
}

void calcul(int logamx)
{
    for (int i=1; i<=ncurent; ++i)
        dp[i][0]=euler[i];
    for (int j=1; j<=logamx; ++j)
        for (int i=1; i+(1<<j)-1<=ncurent; ++i)
            if (niv[dp[i][j-1]]<niv[dp[i+(1<<(j-1))][j-1]])
                dp[i][j]=dp[i][j-1];
            else
                dp[i][j]=dp[i+(1<<(j-1))][j-1];
}

void afis(int nod1,int nod2,int nr)
{
    if(niv[dp[nod1][nr]]<niv[dp[nod2-(1<<nr)+1][nr]])
        g<<dp[nod1][nr]<<'\n';
    else
        g<<dp[nod2-(1<<nr)+1][nr]<<'\n';
}

void eulerr()
{
    dfs(1);
    logga();
    calcul(loga[ncurent]);
    for (auto w:query)
    {
        int nod1=max(primaaparitie[w.first],primaaparitie[w.second]);
        int nod2=min(primaaparitie[w.first],primaaparitie[w.second]);
        int logaritm=loga[nod1-nod2+1];
        afis(nod2,nod1,logaritm);
    }
}

int main()
{
    read();
    eulerr();
    return 0;
}