Cod sursa(job #2848193)

Utilizator adiaioanaAdia R. adiaioana Data 12 februarie 2022 10:58:26
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.29 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[30][2*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);
    make_rmq();

    PII ans;
    for(int i=1; i<=Q; ++i)
    {
        cin>>x>>y;
        px=pr[x]; py=pr[y];
        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});
    pr[nod]=parg.size()-1;
    rmq[0][parg.size()-1]={niv,nod};

    for(auto nn:G[nod])
        if(!pr[nn])
    {
        euler(nn,niv+1);
        parg.pb({nod,niv});
        rmq[0][parg.size()-1]={niv,nod};
    }
}

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