Cod sursa(job #1589810)

Utilizator robertstrecheStreche Robert robertstreche Data 4 februarie 2016 14:23:31
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.23 kb
#include <cstdio>
#include <vector>
#include <cmath>

#define LOGMAX 21
#define NMAX 200005
#define min(a,b) nivel[a]<nivel[b]?a:b

using namespace std;

vector <int>v[NMAX];

int n,m,nr,x,y,q;
int nivel[NMAX];
int euler[2*NMAX],poz[NMAX];
int rmq[LOGMAX][2*NMAX];

void dfs(int nod){
   euler[++nr]=nod;
   poz[nod]=nr;
   for (auto it:v[nod]){
      nivel[it]=nivel[nod]+1;
      dfs(it);
      euler[++nr]=nod;
   }
}
void rmquery(){
   for (int i=1;i<=nr;i++)rmq[0][i]=euler[i];

   for (int l=1;(1<<l)<=nr;l++)
     for (int i=1;i+(1<<l)-1<=nr;i++)
       rmq[l][i]=min(rmq[l-1][i],rmq[l-1][i+(1<<(l-1))]);
}
int main()
{
     freopen("lca.in","r",stdin);
     freopen("lca.out","w",stdout);

     scanf("%d %d",&n,&q);
     for (int i=2;i<=n;i++){
        scanf("%d",&x);
        v[x].push_back(i);
     }
     dfs(1);
     rmquery();

     for (;q;q--){
        scanf("%d %d",&x,&y);

        int poz1=poz[x];
        int poz2=poz[y];
        if (poz1>poz2)swap(poz1,poz2);

        int loga=log2(poz2-poz1+1);
        printf("%d\n",nivel[rmq[loga][poz1]]<nivel[rmq[loga][poz2-(1<<loga)+1]]?rmq[loga][poz1]:rmq[loga][poz2-(1<<loga)+1]);
     }

     fclose(stdin);
     fclose(stdout);
}