Cod sursa(job #2455672)

Utilizator isa_tudor_andreiAndrei Tudor isa_tudor_andrei Data 12 septembrie 2019 12:14:22
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.54 kb
#include <bits/stdc++.h>
#define NMAX 100000
#define EMAX 400000
#define LOGMAX 50

using namespace std;

vector<int> G[NMAX + 1];
vector<int> v;
vector<int> lvl;
int M[EMAX + 1][LOGMAX + 1], f[NMAX + 1], level[NMAX + 1];
int n, m;

void euler(int node) {
  if( G[node].size() == 0 ) {
    v.push_back(node);
    return ;
  }
  else {
    v.push_back(node);
    for( auto it : G[node] ) {
      euler(it);
      v.push_back(node);
    }
  }
}

int main() {
    ifstream fin("lca.in");
    ofstream fout("lca.out");
    int i, q, k;
    fin>>n>>q;
    int a, b;
    level[1] = 0;
    for( i = 1; i <= n - 1; i ++ ) {
      fin>>a;
      G[a].push_back(i+1);
      level[i + 1] = level[a] + 1;
    }
    euler(1);
    for( i = 1; i <= n; i ++ )
      f[i] = -1;
    int j = 0;
    for( auto it : v ) {
      lvl.push_back(level[it]);
      if( f[it] == -1 )
        f[it] = j;
    ++ j;
    }
    for( i = 0; i < lvl.size(); i ++ )
      M[i][0] = i;
    for( j = 1; (1 << j) <= lvl.size(); j ++ )
      for( i = 0; i + (1<<j) - 1 < lvl.size(); i ++ ) {
        if( lvl[M[i][j-1]] < lvl[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];
      }
    for( i = 1; i <= q; i ++ ) {
      fin>>a>>b;
      a = f[a];
      b = f[b];
      k = log2(b - a + 1);
      if( lvl[M[a][k]] < lvl[M[b - (1 << k ) + 1][k]] )
        fout<<v[M[a][k]];
      else
        fout<<v[M[b - (1 << k ) + 1][k]];
      fout<<endl;
    }

    return 0;
}