Cod sursa(job #3140107)

Utilizator Darius1414Dobre Darius Adrian Darius1414 Data 3 iulie 2023 20:30:53
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.37 kb
#include <fstream>
#define nmx 100005
#include <vector>
using namespace std;
int n,m,x,euler[4*nmx],lvl[4*nmx],firstp[4*nmx],log[2*nmx],dp[20][4*nmx];
vector <int> child[nmx];
void eul(int nod,int niv,int &ct)
{
    euler[++ct]=nod;
    lvl[ct]=niv;
    firstp[nod]=ct;
    for (auto it : child[nod])
    {
        eul(it,niv+1,ct);
        euler[++ct]=nod;
        lvl[ct]=niv;
    }
}
void rmq(int k)
{
    log[1]=0;
    for (int i=2; i<=k; i++)
        log[i]=log[i/2]+1;
    for (int i=1; i<=k; i++)
        dp[0][i]=i;
    for (int i=1; (1<<i)<=k; i++)
        for (int j=1; j<=k-(1<<i)+1; j++)
        {
            int pw=1<<(i-1);
            if (lvl[dp[i-1][j]]<lvl[dp[i-1][j+pw]])
                dp[i][j]=dp[i-1][j];
            else
                dp[i][j]=dp[i-1][j+pw];
        }
}
int lca(int a,int b)
{
    if (a>b) swap(a,b);
    int dif=b-a+1;
    int lg=log[dif];
    int pw=(1<<lg);
    if (lvl[dp[lg][a]]<lvl[dp[lg][b-pw+1]])
        return euler[dp[lg][a]];
    return euler[dp[lg][b-pw+1]];
}
int main()
{
    ifstream f("lca.in");
    ofstream g("lca.out");
    f>>n>>m;
    for (int i=2; i<=n; i++)
    {
        f>>x;
        child[x].push_back(i);
    }
    int c=0;
    eul(1,0,c);
    rmq(c);
    int a,b;
    for (int i=1;i<=m;i++)
    {
        f>>a>>b;
        g<<lca(firstp[a],firstp[b])<<'\n';
    }
}