Cod sursa(job #2604834)

Utilizator isa_tudor_andreiAndrei Tudor isa_tudor_andrei Data 23 aprilie 2020 16:51:58
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.59 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

const int NMAX = 1e5;
const int LOG = 20;

int first[NMAX + 1], euler[2 * NMAX + 1], lista[2 * NMAX + 1], LOGS[2 * NMAX + 1];
int M[2 * NMAX + 1][LOG];
vector<int> G[NMAX + 1];
int poz, n;

void dfs( int node, int depth, int father ) {
  euler[poz] = depth;
  lista[poz] = node;
  first[node] = poz;
  M[poz][0] = poz;
  poz ++;

  for( const auto &it : G[node] ) {
    if( it != father ) {
      dfs(it, depth + 1, node);
      M[poz][0] = poz;
      euler[poz] = depth;
      lista[poz] = node;
      poz ++;
    }
  }
}

void build_RMQ( int d ) {
  int i, j;
  for( j = 1; (1<<j) <= d; j ++ ) {
    for( i = 0; i + (1<<j) <= d; i ++ ) {
      if( euler[M[i][j-1]] < euler[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( int i = 2; i <= 2 * NMAX; i ++ )
    LOGS[i] = 1 + LOGS[i / 2];
}

void querry(int a, int b) {
  int k = LOGS[b - a + 1];
  if( euler[M[a][k]] < euler[M[b-(1<<k)+1][k]] )
    fout<<lista[M[a][k]]<<"\n";
  else
    fout<<lista[M[b-(1<<k)+1][k]]<<"\n";
}

int main() {
    int m;
    fin>>n>>m;
    for( int i = 2; i <= n; i ++ ) {
      int x;
      fin>>x;
      G[x].push_back(i);
      G[i].push_back(x);
    }
    dfs(1, 0, 0);
    build_RMQ(2*n - 1);
    for( int i = 1; i <= m; i ++ ) {
      int u, v;
      fin>>u>>v;
      int st = min(first[u], first[v]);
      int dr = max(first[u], first[v]);
      querry(st, dr);
    }
    return 0;
}