Cod sursa(job #2325480)

Utilizator filicriFilip Crisan filicri Data 22 ianuarie 2019 17:44:21
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.68 kb
#include <fstream>
#include <queue>
#define nmax 100004
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n,m,fa[nmax],a,b,en[nmax],et[2*nmax],k=1,posa,posb,rmq[2*nmax][20],lg[2*nmax],dim;
// en[i]=corespondentul nodului initial i, pentru par.eu.
queue <int> q;
vector <int> G[nmax];
void bfs (void)
{
    int k=2;
    en[1]=1;
    q.push(1);
    while (!q.empty())
    {
        int node=q.front();
        q.pop();
        for (auto ne:G[node])
        {
            if (!en[ne])
            {
                en[ne]=k++;
                q.push(ne);
            }
        }
    }
}
void etour (int node)
{
    while (!G[node].empty())
    {
        int x=G[node].back();
        G[node].pop_back();
        et[++k]=en[x];
        etour(x);
    }
    et[++k]=en[fa[node]];
}
int getpos (int x)
{
    for (int i=1;i<=2*n-1;i++)
        if (et[i]==x) return i;
}
void constr (int dim)
{
    for (int i=1;i<=dim;i++) rmq[i][0]=et[i];
    for (int j=1;(1<<j)<=dim;j++)
        for (int i=1;i+(1<<j)-1<=dim;i++)
            rmq[i][j]=min(rmq[i][j-1],rmq[i+(1<<(j-1))][j-1]);
    lg[1]=0;
    for (int i=2;i<=dim;i++) lg[i]=lg[i/2]+1;
}
int RMQ (int x,int y)
{
    return min(rmq[x][lg[y-x+1]],rmq[y-(1<<lg[y-x+1])+1][lg[y-x+1]]);
}
int main()
{
    f>>n>>m;
    fa[1]=1;
    for (int i=2;i<=n;i++)
    {
        f>>fa[i];
        G[fa[i]].push_back(i);
    }
    bfs();
    et[1]=1;
    etour(1);
    constr(2*n);
    for (int i=1;i<=m;i++)
    {
        f>>a>>b;
        posa=getpos(en[a]);
        posb=getpos(en[b]);
        g<<RMQ(min(posa,posb),max(posa,posb))<<'\n';
    }
    f.close();
    g.close();
    return 0;
}