Cod sursa(job #2432917)

Utilizator smoc_georgemarianSmoc George-Marian smoc_georgemarian Data 25 iunie 2019 14:41:46
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb
#include <bits/stdc++.h>
#define NMAX 100009
#define LOGMAX 40
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n,m,cate,x,y;
int level[NMAX];
vector <int> g[NMAX];
int euler[2*NMAX];

int ind[NMAX];
int M[2*NMAX][LOGMAX];
bool uz[NMAX];

void citire();
void  dfs(int k, int lvl);
void build();
int query();
int main()
{
    citire();
    dfs(1,1);

    build();
    for(int i=1;i<=m;i++)
        {
         fin>>x>>y;
         x=ind[x];
         y=ind[y];
         fout<<query()<<'\n';
        }
    return 0;
}
void citire()
{
  int i,tata;
  fin>>n>>m;
  for(i=2;i<=n;i++)
    {
     fin>>tata;
     g[tata].push_back(i);
     g[i].push_back(tata);
    }

}
void dfs(int k, int lvl)
{int i;
    euler[++cate]=k;
    level[cate]=lvl;
    if(!ind[k])
        ind[k]=cate;
    uz[k]=1;
    for(i=0;i<g[k].size();i++)
        if(!uz[g[k][i]])
        {
         dfs(g[k][i],lvl+1);
         euler[++cate]=k;
         level[cate]=lvl;
        }
}
void build()
{
  int i,j;
  for(i=1;i<=2*n-1;i++)
    M[i][0]=i;
  for(j=1;(1<<j)<=2*n-1;j++)
      for(i=1;  i+(1<<j) -1 <=  2*n-1  ;i++)
          {

           if(level[M[i][j-1]]<level[ M[i+(1<<(j-1))][j-1] ])
              M[i][j]=M[i][j-1];
              else
                M[i][j]=M[i+(1<<(j-1) )   ][j-1];

          }
}
int query()
{
 int lg;
 if(x<y)
    swap(x,y);
 lg=log2(x-y+1);
 if(    level[  M[x-(1<<lg)+1][lg]   ]  < level[ M[y][lg]    ])
      return euler[  M[x-(1<<lg)+1][lg]  ];

        return euler[  M[y][lg]  ];
}