Cod sursa(job #2284958)

Utilizator ZappaManIosif Adrian-Mihai ZappaMan Data 17 noiembrie 2018 20:04:57
Problema Stramosi Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.38 kb
#include <stdio.h>
#include <vector>

using namespace std;

const int NMAX = 100005;
const int LMAX = 20;
const int MMAX = 2000005;

int N, M;
int T[LMAX][NMAX];
int L[NMAX];

vector<int> G[NMAX];

void dfs(int child, int lev) {
   L[child] = lev;

   for (auto n : G[child]) {
      dfs(n, lev+1);
   }
}


void build() {
   for (int k = 1; (1 << k) <= N; ++k) {
      for (int i = 1; i <= N; ++i) {
         T[k][i] = T[k-1][T[k-1][i]];
      }
   }
}

int lca(int x, int y) {

   if (L[x] < L[y]) {
      int aux = x;
      x = y;
      y = aux;
   }

   int lg1, lg2;
   for (lg1 = 1; (1 << lg1) <= L[x]; ++lg1);
   for (lg2 = 1; (1 << lg2) <= L[y]; ++lg2);

   for (int k = lg1; k >= 0; --k) {
      if (L[x] - L[y] >= (1 << k)) {
         x = T[k][x];
      }
   }

   if (x == y) {
      return x;
   }

   for (int k = lg2; k >= 0; --k) {
      if (T[k][x] && T[k][x] != T[k][y]) {
         x = T[k][x];
         y = T[k][y];
      }
   }
   return T[0][x];
}

int main() {
   freopen("lca.in", "r", stdin);
   freopen("lca.out", "w", stdout);

   scanf("%d%d", &N, &M);

   for (int i = 2; i <= N; ++i) {
      int parent;
      scanf("%d", &parent);

      G[parent].push_back(i);
      T[0][i] = parent;
   }

   dfs(1, 0);

   build();

   for (int i = 0; i < M; ++i) {
      int x,y;
      scanf("%d %d", &x, &y);
      printf("%d\n", lca(x,y));
   }

   fclose(stdin);
   fclose(stdout);
   return 0;
}