Cod sursa(job #2973363)

Utilizator andreibrosPeta Andrei Mathias andreibros Data 31 ianuarie 2023 20:32:42
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.67 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int NMAX=100000;

int E[2*NMAX+5];
int L[NMAX+5];
int level[2*NMAX+5]; // 2n-1 la toate marimea
int First[NMAX+5];
int RMQ[20][2*NMAX+5];
int lg2[2*NMAX+5];
vector<int>graf[NMAX+5];
bool visited[NMAX+5];

int k; // indicele curent folosit pentru vectorul E

void euler(int x)
{
    visited[x]=1;
    E[++k]=x;
    if(!First[x])
        First[x]=k;

    int y;
    for(unsigned int i=0; i<graf[x].size(); i++)
    {
        y=graf[x][i];
        if(visited[y]==0)
        {
            L[y]=1+L[x];
            euler(y);
            E[++k]=x;
        }
    }
}
void rmq()
{

    for(int i=2; i<=k; i++)
        lg2[i]=lg2[i/2]+1;
    for(int i=1; i<=k; i++)
        level[i]=L[E[i]];
    for(int i=1; i<=k; i++)
        RMQ[0][i]=i;
    for(int i=1; i<=lg2[k]; i++)
    {
        for(int j=1; j<=k; j++)
        {
            RMQ[i][j]=RMQ[i-1][j];
            if(level[RMQ[i-1][j-(1<<(i-1))]]<level[RMQ[i][j]])
                RMQ[i][j]=RMQ[i-1][j-(1<<(i-1))];
            cout<<RMQ[i][j]<<" ";
        }
        cout<<endl;
    }
}

int main()
{ int n,m,x,y;
  in>>n>>m;

  for(int i=2; i<=n; i++)
  {
      in>>x;
      graf[x].push_back(i);
  }
   euler(1);
   rmq();
   int l,idx;
   for(int i=1; i<=m; i++)
   {
       in>>x>>y;
       x=First[x];
       y=First[y];
       if(x>y)
        swap(x,y);
       l=lg2[y-x+1];
       idx=RMQ[l][y];

       if(level[idx]>level[RMQ[l][x+(1<<l)-1]])
            idx=RMQ[l][x+(1<<l)-1];
        out<<E[idx]<<'\n';

   }

    return 0;
}