Cod sursa(job #2010485)

Utilizator AlexandruLuchianov1Alex Luchianov AlexandruLuchianov1 Data 13 august 2017 12:07:10
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.06 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;
ifstream in ("lca.in");
ofstream out ("lca.out");
int const nmax = 100000;

vector<int> g[1 + nmax];
int n;
int v[1 + 2*nmax], nv;
int pos[1 + 2*nmax], depth[1 + nmax];

void dfs(int node){
  for(int i = 0; i < g[node].size(); i++){
    if(0 < i) {
      v[++nv] = node;
      pos[node] = nv;
    }
    depth[g[node][i]] = depth[node] + 1;
    dfs(g[node][i]);
  }
  if(g[node].size() <= 1) {
    v[++nv] = node;
    pos[node] = nv;
  }
}

int binarysearch(int from, int to, int dif){
  //cout<<from<<" "<<to<<" "<<dif<<'\n';
  if(from < to) {
    int mid = (from + to) / 2;
    if((1 << mid) < dif) {
      return binarysearch(mid + 1, to, dif);
    } else {
      return binarysearch(from, mid, dif);
    }
  } else {
    return from;
  }
}

//rmq[i][p] imi tine minte pozitia j din v, astfel incat depth[v[j]] e minim pe   intervalul [i, i + 2^p]

int rmq[20][1 + 2 * nmax];

int minrmq(int from, int to, int pow2) {
  int i = rmq[pow2][from];
  int j = rmq[pow2][to - (1 << pow2)];
  if(depth[v[i]] < depth[v[j]]){
    return i;
  } else {
    return j;
  }
}

void computermq() {
  for(int j = 1 ;  j < nv ;j++){
    if(depth[v[j]] < depth[v[j + 1]]) {
      rmq[0][j] = j;
    } else{
      rmq[0][j] = j + 1;
    }
  }
  for(int i = 1; i < 20; i++) {
    int lim = nv - (1 << i);

    for(int j = 1; j <= lim ;j++ ) {
      rmq[i][j] = minrmq(j, j + (1 << i), i - 1);
    }
  }
}

int main() {
  int q;
  in >> n >> q;
  int a, b;
  for(int i = 2; i <= n; i++) {
    in >> a;
    g[a].push_back(i);
  }
  dfs(1);

  computermq(); //ai rmq


  for(int i = 0 ; i < q; i++){
    in >> a >> b;
    if(a == b) {
      out << a << '\n';
    } else {
      int x = pos[a];
      int y = pos[b];
      if(y < x)
        swap(x, y);
      //cout<<x<<" "<<y<<" -> "<<endl;
      int pow2 = binarysearch(0, 21, y - x);
      if(y - x < (1<<pow2))
        pow2--;
      out<< v[minrmq(x , y , pow2)] << '\n';

    }
  }
  return 0;
}