Cod sursa(job #2284851)

Utilizator ZappaManIosif Adrian-Mihai ZappaMan Data 17 noiembrie 2018 18:08:02
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.67 kb
#include <stdio.h>
#include <math.h>
#include <vector>

using namespace std;

const int NMAX =  100005;
const int MMAX = 2000005;
const int LOGN = 20;
const int EMAX = NMAX << 1;

int E[EMAX];
int L[EMAX];
int F[NMAX];
int l[EMAX];

int rmq[LOGN][EMAX];

vector<int> G[NMAX];

int E_ix = 0;
int N, M;

void dfs(int child, int level) {
   E[++E_ix] = child;
   L[E_ix] = level;
   F[child] = E_ix;

   for (auto node : G[child]) {
      dfs(node, level + 1);
      E[++E_ix] = child;
      L[E_ix] = level;
   }
}

void rmq_build() {
   l[1] = 0;
   for (int i = 2; i <= E_ix; ++i) {
      l[i] = l[i / 2] + 1;
   }

   for (int i = 1; i <= E_ix; ++i) {
      rmq[0][i] = i;
   }

   for (int j = 1; (1 << j) < E_ix; j++) {
      int sh = (1 << (j - 1));

      for (int i = 1; i + (1 << j)  <= E_ix; ++i) {
         rmq[j][i] = rmq[j-1][i];
         if (L[rmq[j-1][i+sh]] < L[rmq[j][i]]) {
            rmq[j][i] = rmq[j-1][i+sh];
         }
      }
   }
}


void rmq_q(int x, int y) {
   if (x > y) {
      int aux = x;
      x = y;
      y = aux;
   }

   int diff = y - x + 1;
   int ldiff = l[diff];
   int ix = rmq[ldiff][x];
   if (L[rmq[ldiff][y - (1 << ldiff) + 1]] < L[ix]) {
      ix = rmq[ldiff][y - (1 << ldiff) + 1];
   }
   printf("%d\n", E[ix]);
}


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 val;
      scanf("%d", &val);
      G[val].push_back(i);
   }

   dfs(1, 0);

   rmq_build();

   for (int i = 0; i < M; ++i) {
      int x,y;
      scanf("%d%d",&x,&y);
      int fx = F[x];
      int fy = F[y];
      rmq_q(fx, fy);
   }

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