Cod sursa(job #3271496)

Utilizator Sorin_GabrielGabara Sorin Gabriel Sorin_Gabriel Data 26 ianuarie 2025 13:08:39
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 kb
#include <bits/stdc++.h>
#include <fstream>
#define VMAX 100005
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");

vector<int> graf[VMAX];
int tati[VMAX];
int nivel[VMAX];
int prima_aparitie[VMAX];
int rmq[(int)log2(VMAX)+2][VMAX];
int pow2[VMAX];
vector<int> euler_tour;

void dfs(int nod)
{
    euler_tour.push_back(nod);
    if(prima_aparitie[nod]==0)
        prima_aparitie[nod]=euler_tour.size()-1;

    for(int i=0;i<graf[nod].size();i++)
    {
        dfs(graf[nod][i]);
        euler_tour.push_back(nod);
    }
}

int main()
{
    ios_base::sync_with_stdio(0);
    int n,m,i,j,k,t,q,nr,minim,maxim,suma,nod;
    fin>>n>>m;
    tati[1]=1;
    nivel[1]=1;
    for(i=2;i<=n;i++)
    {
        fin>>j;
        tati[i]=j;
        graf[j].push_back(i);
        nivel[i]=nivel[j]+1;
    }

    dfs(1);
    //ptr diferenta de 1 comparam direct din euler_tour
    for(j=1;j<euler_tour.size();j++) // rmq[0] - dif 1 / 2 numere
    {
        k=euler_tour[j];
        t=euler_tour[j-1];
        if(nivel[k]>nivel[t])
            rmq[0][j-1]=t;
        else
            rmq[0][j-1]=k;
    }

// rmq[1] - dif 2 / 3 numere != 4
//rmq[2] - dif 4 / 5 numere != 8
// rmq[3] - dif 8
// rmq[4] - dif 16

    for(i=1;(1<<(i-1))<n;i++)
    {
        for(j=0;j+(1<<(i-1))<euler_tour.size();j++)
        {
            k=rmq[i-1][j];
            t=rmq[i-1][j+(1<<(i-1))];
            if(nivel[k]>nivel[t])
                rmq[i][j]=t;
            else
                rmq[i][j]=k;
        }
    }

    for(i=1,j=0;i<=n;i*=2,j++)
        pow2[i]=j;

    for(i=2;i<=n;i++)
        if(pow2[i]==0)
            pow2[i]=pow2[i-1];

    for(i=0;i<m;i++)
    {
        fin>>j>>k;
        if(prima_aparitie[j]>prima_aparitie[k])
            swap(j,k);
        nod=j;
        j=prima_aparitie[j];
        k=prima_aparitie[k];
        k=k-j;


        while(k)
        {
            t=rmq[pow2[k]][j];
            if(nivel[nod]>nivel[t])
                nod=t;
            j+=1<<pow2[k];
            k-=1<<pow2[k];
        }
        fout<<nod<<'\n';
    }


    return 0;
}