Cod sursa(job #3203252)

Utilizator DomnulMilandruMilandru Nicon-David DomnulMilandru Data 13 februarie 2024 13:16:31
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.63 kb

#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int n,q;
int x,y;
vector<vector<int>> A;
vector<int> nivel,euler,first_app;
void dfs(int nod)
{
    for(int i=0;i<A[nod].size();i++)
    {
        int vecin=A[nod][i];
        nivel[vecin]=nivel[nod]+1;
        euler.push_back(vecin);
        first_app[vecin]=euler.size()-1;
        dfs(vecin);
        euler.push_back(nod);
    }
}
int N;
vector<vector<int>> rmq;
vector<int> E;
int main()
{
   cin>>n>>q;
   A.resize(n+1);
   nivel.resize(n+1);
   first_app.resize(n+1);
   for(int i=1;i<n;i++)
   {
       cin>>x;
       A[x].push_back(i+1);
   }
    euler.push_back(1);
    first_app[1]=0;
    dfs(1);
    N=euler.size();
    rmq.resize(log2(N)+1);
    rmq[0].resize(N);
    for(int i=0;i<N;i++)
       rmq[0][i]=euler[i];
    for(int p=1;(1<<p)<N;p++)
    {
        rmq[p].resize(N);
        for(int i=0;i<N;i++)
        {
            rmq[p][i]=rmq[p-1][i];
            int j=i+(1<<(p-1));
            if(j<N)
              if(nivel[rmq[p-1][j]]<nivel[rmq[p][i]])
                 rmq[p][i]=rmq[p-1][j];
        }
    }
    E.resize(N+1);
    for(int i=2;i<=N;i++)
       E[i]=E[i/2]+1;
    for(int i=0;i<q;i++)
    {
        cin>>x>>y;
        int st=first_app[x];
        int dr=first_app[y];
        if(st>dr)
           swap(st,dr);
        int l=dr-st+1;
        int q=(1<<E[l]);
       if(nivel[rmq[E[l]][st]]<nivel[rmq[E[l]][dr-q+1]])
            cout<<rmq[E[l]][st]<<'\n';
        else
           cout<<rmq[E[l]][dr-q+1]<<'\n';
    }
    return 0;
}