Cod sursa(job #2957231)

Utilizator and_Turcu Andrei and_ Data 21 decembrie 2022 23:49:43
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.66 kb
#include <bits/stdc++.h>
#define N 100007
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

int n,q;
vector<int> a[N];
vector<int> ordine(2*N-1,-1); int poz;
vector<int> aparitie_fin(N,0);
vector<int> adancime(N,0);

void Tur(int x,int depth)
{
    poz++;
    aparitie_fin[x] = poz;
    ordine[poz]=x;
    adancime[x]= depth;
    for( auto y:a[x] )
    {
        Tur(y,depth+1);
        poz++;
        aparitie_fin[x] = poz;
        ordine[poz]=x;
    }
}

int RMQ[30][2*N-1];
vector<int>putere(N,0);


void Gen_RMQ()
{
    for(int i=2;i<=2*n-1;i++)
        putere[i]=putere[i/2]+1;
    for(int i=1;i<=2*n-1;i++)
        RMQ[0][i]=ordine[i];
    for(int k=1;k<=putere[2*n-1];k++)
        for(int i=1;i<=2*n -(1<<k) ;i++)
        {
            int dist= (1<<(k-1));
            RMQ[k][i]=RMQ[k-1][i];
            if( adancime[ RMQ[k-1][i+dist] ] < adancime[ RMQ[k][i] ] )
                RMQ[k][i]=RMQ[k-1][i+dist];
        }
    for(int i=1;i<=2*n-1;i++)
        cout << RMQ[1][i] << " ";
}

void Rezolvare(int x,int y)
{
    int st=min( aparitie_fin[x],aparitie_fin[y] );
    int dr=max( aparitie_fin[x],aparitie_fin[y] );
    int dist=dr-st+1;
    int p=putere[dist];
    dist= (1<<p);
    if( adancime[ RMQ[p][st] ]<adancime[ RMQ[p][dr-dist+1] ]  )
        fout << ordine[ RMQ[p][st] ] << '\n';
    else
        fout << ordine[ RMQ[p][dr-dist+1] ] << '\n';
}


int main()
{
    fin >> n >> q ;
    for(int i=2;i<=n;i++)
    {
        int x;
        fin >> x;
        a[x].push_back(i);
    }
    Tur(1,0);
    Gen_RMQ();
    for(int i=1;i<=q;i++)
    {
        int x,y;
        fin >> x >> y;
        Rezolvare(x,y);
    }

    fin.close();
    fout.close();
    return 0;
}