Cod sursa(job #2858080)

Utilizator TudosieRazvanTudosie Marius-Razvan TudosieRazvan Data 26 februarie 2022 22:16:06
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.9 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstring>
#include <climits>
#include <unordered_map>

#define NMAX 100003

//Solutia cu Euler
using namespace std;

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

int n,m,kEuler;
int niv[NMAX];//nivelul fiecarui nod
int primaAp[2*NMAX];//prima aparitie in nodurile euler
int noduriEuler[2*NMAX];//vectorul de muchii euler
int rmq[128][2*NMAX];
int p[2*NMAX];//precalcularea puterilor de 2

vector<int>graf[NMAX];

void dfs(int nod,int nivel)
{
    niv[nod]=nivel;
    primaAp[nod]=++kEuler;
    noduriEuler[kEuler]=nod;
    for(int i=0; i<graf[nod].size(); i++)
    {
        dfs(graf[nod][i],nivel+1);
        noduriEuler[++kEuler]=nod;
        
    }
   
}

void lca(int L,int R)
{
    int lung = R - L + 1;
    int val = p[lung];
	
    if(niv[rmq[val][L]]< niv[rmq[val][R+1 - (1 << val)]] )
    {
        fout<<rmq[val][L]<<"\n";
        return;
    }
	fout<<rmq[val][R+1 - (1 << val)]<<"\n";
}

int main()
{

    fin >> n >> m;
    for(int i=2; i<=n; i++)
    {
        int x;
        fin>>x;
       
        graf[x].push_back(i);
    }
    
    dfs(1,0);
    p[1]=0;
    for(int i=2; i<=kEuler; i++)
    {
        p[i]=p[i/2]+1;
    }
    

    //aplic rmq pe vectorul de euler
    for(int i=1; i<=kEuler; i++)
    {
        rmq[0][i]=noduriEuler[i];
    }
    
    for(int i=1; (1<<i)<=kEuler; i++)
    {
        int lungSecv=(1<<i);
        for(int j=1; j+lungSecv-1<=kEuler; j++)
        {
            int st=j;
            int dr=j+(1<<(i-1))-1;
            if(niv[rmq[i-1][st]]<niv[rmq[i-1][dr]])
            {
                rmq[i][j]=rmq[i-1][st];
            }
            else{
                rmq[i][j]=rmq[i-1][dr];
            }
        }
    }

    for(int i=1; i<=m; i++)
    {
        int x,y;
        fin>>x>>y;
        lca(min(primaAp[x],primaAp[y]),max(primaAp[x],primaAp[y]));
    }
    return 0;
}