Cod sursa(job #2136663)

Utilizator NannyiMaslinca Alecsandru Mihai Nannyi Data 20 februarie 2018 09:03:37
Problema Lowest Common Ancestor Scor 100
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];

int n,m,ncurent,tata[nmax],logarits[nmax*2+5],logmx,niv[nmax],primaaparitie[nmax*2+5],ciclueuler[nmax*2+5];
int dp[nmax*2+5][20];
void read()
{
    f>>n>>m;
    for (int i=2; i<=n; ++i)
    {
        int a;
        f>>a;
        tata[i]=a;
        Q[a].push_back(i);
    }
}

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

void logas()
{
    int power=0;
    for (int i=1; i<=ncurent; i<<=1,++power);
    logmx=power-1;
    for (int i=2; i<=ncurent; ++i)
        logarits[i]=logarits[i>>1]+1;
}

void dinamica()
{
    for (int i=1; i<=ncurent; ++i)
        dp[i][0]=ciclueuler[i];
    for (int j=1; j<=logmx; ++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 solve()
{
    euler(1);
    --ncurent;
    logas();
    dinamica();
}

void query()
{
    int a,b;
    for (int i=1; i<=m; ++i)
    {
        f>>a>>b;
        int bneed=primaaparitie[b];
        int aneed=primaaparitie[a];
        if (bneed<aneed)
            swap(bneed,aneed);
        int getloga=logarits[bneed-aneed+1];
        if (niv[dp[aneed][getloga]]<niv[dp[bneed-(1<<getloga)+1][getloga]])
            g<<dp[aneed][getloga]<<'\n';
        else
            g<<dp[bneed-(1<<getloga)+1][getloga]<<'\n';
    }
}

int main()
{
    read();
    solve();
    query();
    return 0;
}