Cod sursa(job #1394196)

Utilizator c0rn1Goran Cornel c0rn1 Data 20 martie 2015 09:15:55
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.59 kb
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#define NMAX 100008
#define LMAX 30

using namespace std;

int n, m;
vector<int> v[NMAX];
int eul[NMAX], revEul[NMAX], depth[NMAX];
int lg2[NMAX], ind[NMAX][LMAX];

void read()
{
   int x;
   scanf("%d %d\n", &n, &m);
   for (int i = 2; i <= n; ++i){
      scanf("%d ", &x);
      v[x].push_back(i);
   }
}

void dfs(int x, int dep)
{
   eul[++eul[0]] = x; revEul[x] = eul[0]; depth[eul[0]] = dep;
   for (vector<int>::iterator it = v[x].begin(); it != v[x].end(); ++it){
      dfs(*it, dep+1);
      eul[++eul[0]] = x; depth[eul[0]] = dep;
   }
}

void rmq()
{
   for (int i = 2; i <= eul[0]; ++i)
      lg2[i] = lg2[i>>1] + 1;
   for (int i = 1; i <= eul[0]; ++i)
      ind[i][0] = i;
   for (int j = 1; j <= lg2[eul[0]]; ++j){
      for (int i = 1; i <= eul[0] - (1 << j) + 1; ++i){
         if (depth[ind[i][j-1]] < depth[ind[i+(1<<(j-1))][j-1]]){
            ind[i][j] = ind[i][j-1];
         }
         else {
            ind[i][j] = ind[i+(1<<(j-1))][j-1];
         }
      }
   }

}

int LCA(int x, int y)
{
   x = revEul[x]; y = revEul[y];
   if (x > y) x ^= y ^= x ^= y;
   int l = lg2[y-x+1];
   if (depth[ind[x][l]] < depth[ind[y-(1<<l)+1][l]])
      return eul[ind[x][l]];
   return eul[ind[y-(1<<l)+1][l]];
}

int main()
{
   freopen("lca.in", "r", stdin);
   freopen("lca.out", "w", stdout);
   int x, y;
   read();
   dfs(1, 0);
   rmq();
   for (int T = 1; T <= m; ++T){
      scanf("%d %d\n", &x, &y);
      printf("%d\n", LCA(x, y));
   }

   return 0;
}