Cod sursa(job #2957238)

Utilizator and_Turcu Andrei and_ Data 22 decembrie 2022 00:08:50
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.76 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(2*N,0);

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

int RMQ[20][2*N-1];
vector<int>putere(2*N-1,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]=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';
//        cout << "DA";
}


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

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