Cod sursa(job #2575234)

Utilizator isa_tudor_andreiAndrei Tudor isa_tudor_andrei Data 6 martie 2020 12:20:29
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.81 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 1e5;

struct Node{
  int val, depth;
};

Node aint[8 * NMAX];
int first[NMAX + 1];
vector<int> G[NMAX + 1];
int poz, n;

void update( int node, int st, int dr, int poz, Node x ) {
  if( st == dr ) {
    aint[node] = x;
    return ;
  }

  int mid = (st + dr) / 2;
  if( poz <= mid )
    update(2 * node, st, mid, poz, x);
  else
    update(2 * node + 1, mid + 1, dr, poz, x);

  if( aint[2*node].depth <= aint[2*node + 1].depth )
    aint[node] = aint[2*node];
  else
    aint[node] = aint[2*node + 1];
}

Node query( int node, int st, int dr, int left, int right ) {
  if( dr < left || st > right )
    return {NMAX + 1, NMAX + 1};

  if( left <= st && dr <= right )
    return aint[node];

  int mid = (st + dr) / 2;
  Node a = query(2*node, st, mid, left, right);
  Node b = query(2*node + 1, mid + 1, dr, left, right);
  if( a.depth <= b.depth )
    return a;
  else
    return b;
}

void dfs( int node, int depth, int father ) {
  ++ poz;
  update( 1, 1, 2*n - 1, poz, {node, depth} );
  if( first[node] == 0 )
    first[node] = poz;

  for( const auto &it : G[node] ) {
    if( it != father ) {
      dfs(it, depth + 1, node);
      ++ poz;
      update( 1, 1, 2*n - 1, poz, {node, depth} );
    }
  }
}

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);
    for( int i = 1; i <= m; i ++ ) {
      int u, v;
      fin>>u>>v;
      int st = first[u];
      int dr = first[v];
      if( st > dr )
        swap(st, dr);
      Node ans = query(1, 1, 2*n - 1, st, dr);
      fout<<ans.val<<"\n";
    }
    return 0;
}