Cod sursa(job #2848222)

Utilizator adiaioanaAdia R. adiaioana Data 12 februarie 2022 11:29:00
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.42 kb
#include <fstream>
#include <cmath>
#include <vector>
#define pb push_back
#define Nmax 100100
#define PII pair<int,int>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int pr[Nmax];
PII rmq[20][2*Nmax];
bool viz[Nmax];
vector <PII> parg;
vector <int> G[Nmax];

void euler(int nod,int niv);
inline void make_rmq();
int main()
{
    int N,Q,x,y,px,py,lg,p2;
    cin>>N>>Q;
    for(int i=2; i<=N; ++i)
    {
        cin>>x;
        G[x].pb(i);
    }
    parg.pb({0,0});
    euler(1,1);

    for(int i=1; i<parg.size(); ++i)
    {
        rmq[0][i]={parg[i].second,parg[i].first};
        if(!pr[parg[i].first])
            pr[parg[i].first]=i;
    }
    make_rmq();

    PII ans;
    for(int i=1; i<=Q; ++i)
    {
        cin>>x>>y;
        px=pr[x]; py=pr[y];
        if(px>py) swap(px,py);
        lg=py-px+1;
        p2=log2(lg);
        ans=min(rmq[p2][px],rmq[p2][py-(1<<p2)+1]);
        cout<<ans.second<<'\n';
    }
    return 0;
}

void euler(int nod,int niv)
{
    parg.pb({nod,niv});
    viz[nod]=1;
    for(auto nn:G[nod])
        if(!viz[nn])
        {
            euler(nn,niv+1);
            parg.pb({nod,niv});
        }
}

inline void make_rmq()
{
    for(int p2=1, doi=2; doi<parg.size(); doi*=2,++p2)
        for(int i=1; i+doi-1<parg.size(); ++i)
            rmq[p2][i]=min(rmq[p2-1][i],
                           rmq[p2-1][i+(doi/2)]);
}