Cod sursa(job #3174857)

Utilizator NathanBBerintan Emanuel Natanael NathanB Data 25 noiembrie 2023 10:31:54
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.9 kb
#include <bits/stdc++.h>

using namespace std;
//ofstream fout("fisier.out");
typedef long long ll;
#define Inf 0x3f3f3f3f
//#define cout fout
const int Lim = 1e5,Nmax=1e5+1,LOG=21;
char s[Lim];
int p = Lim-1;

void next()
{
    if(++p == Lim)
    fread(s,1,Lim,stdin), p=0;
}

void Get(int &x)
{
    while(!isdigit(s[p])) next();
    for(x=0;isdigit(s[p]);next())
        x = x*10 + s[p] - '0';
}

int t[Nmax];
vector<int> G[Nmax];
int n,m;

int v[2*Nmax],lev[2*Nmax],rmq[LOG][2*Nmax],poz[Nmax];
int cnt = 0;

void Dfs(int nod,int niv)
{
    v[++cnt] = nod;
    lev[cnt] = niv;
    poz[nod] = cnt;
    for(auto c:G[nod])
    {
        Dfs(c,niv+1);
        v[++cnt] = nod;
        lev[cnt] = niv;
    }
}

int main()
{
    freopen("fisier.in","r",stdin);
    freopen("fisier.out","w",stdout);
    cin>>n>>m;
    //printf("%d %d\n",n,m);
    for(int i=2;i<=n;i++)
    {
        int c;
        cin>>c;
        G[c].emplace_back(i);
    }
    Dfs(1,1);
    for(int i=1;i<=cnt;i++)
        rmq[0][i] = i;
    for(int k=1;(1<<k)<=cnt;k++)
        for(int i=1;i+(1<<k)<=cnt;i++)
    {
        int p1 = rmq[k-1][i], p2=rmq[k-1][i+(1<<(k-1))];
        if(lev[p1] < lev[p2])
            rmq[k][i] = p1;
        else
            rmq[k][i] = p2;
    }
    /*for(int i=1;i<=cnt;i++)
        printf("%d ",v[i]);
    printf("\n");
    for(int i=1;i<=cnt;i++)
        printf("%d ",lev[i]);
    printf("\n");*/
    for(int i=1;i<=m;i++)
    {
        int st,dr;
        cin>>st>>dr;
        st = poz[st];
        dr = poz[dr];
        if(st>dr) swap(st,dr);
        int l=0;
        l = log2(dr-st+1);
        int p1 = rmq[l][st], p2 = rmq[l][dr-(1<<l)+1];
        //printf("st dr p1 p2 = %d %d %d %d\n",st,dr,p1,p2);
        int ans;
        if(lev[p1] < lev[p2])
            ans = v[p1];
        else ans = v[p2];
        printf("%d\n",ans);
    }
    return 0;
}