Cod sursa(job #2325509)

Utilizator filicriFilip Crisan filicri Data 22 ianuarie 2019 18:22:26
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.67 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,fr[2*nmax];
// 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]=x;
        if (fr[x]==0) fr[x]=k;
        etour(x);
    }
    et[++k]=fa[node];
}
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]=fr[1]=1;
    etour(1);
    constr(2*n-1);
    for (int i=1;i<=m;i++)
    {
        f>>a>>b;
        if (a==b)
        {
            g<<a<<'\n';
            continue;
        }
        g<<RMQ(min(fr[a],fr[b]),max(fr[a],fr[b]))<<'\n';
    }
    f.close();
    g.close();
    return 0;
}