Cod sursa(job #930051)

Utilizator PetcuIoanPetcu Ioan Vlad PetcuIoan Data 27 martie 2013 13:36:36
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.86 kb
#include<cstdio>
#include<cassert>
#include<cstring>

#include<algorithm>
#include<vector>
#include<iostream>
#include<fstream>
#include<queue>

using namespace std;

int u, vis[100005], ind[100005], num[100005], pos[100005], init[200005], p2[400005], dp[18][400005];
vector<int> graph[100005];

void rmq(){
  p2[2] = 1;
  int t = 2;
  while(t <= u){
    t = t << 1;
    p2[t] = p2[t >> 1] + 1;
  }
  for(int i = 3; i < t; ++i)
    if(!p2[i])
      p2[i] = p2[i - 1];

  for(int i = 1; i <= u; ++i)
    dp[0][i] = init[i];

  int x;
  for(int i = 1; i <= p2[u] + 1; ++i)
    for(int j = 1; j <= u; ++j){
      x = j + (1 << (i - 1));
      if(x <= u)
        dp[i][j] = min(dp[i - 1][j], dp[i - 1][x]);
      else
        dp[i][j] = dp[i - 1][j];
    }

}

int query(int left, int right){
  int p = p2[right - left + 1];
  return min(dp[p][left], dp[p][left + (right - left + 1) - (1 << p)]);
}

void bfs(){
  int n = 0;
  queue<int> q;
  vis[1] = 1;
  ind[1] = ++n;
  num[n] = 1;
  q.push(1);

  while(!q.empty()){
    int now = q.front();
    q.pop();

    for(int i = 0; i < graph[now].size(); ++i)
      if(!vis[graph[now][i]]){
        vis[graph[now][i]] = 1;
        ind[graph[now][i]] = ++n;
        num[n] = graph[now][i];
        q.push(graph[now][i]);
      }

  }

}

void dfs(int x){
  vis[x] = 1;
  init[++u] = ind[x];
  pos[x] = u;

  for(int i = 0; i < graph[x].size(); ++i)
    if(!vis[graph[x][i]]){
      dfs(graph[x][i]);
      init[++u] = ind[x];
    }
}

int main(){
  ifstream in("lca.in");
  ofstream out("lca.out");

  int n, m, x;

  in >> n >> m;

  for(int i = 2; i <= n; ++i){
    in >> x;
    graph[x].push_back(i);
    graph[i].push_back(x);
  }

  bfs();
  memset(vis, 0, sizeof(vis));
  dfs(1);

  rmq();

  int y;
  for(int i = 0; i < m; ++i){
    in >> x >> y;
    if(pos[x] > pos[y])
      swap(x, y);
    out << num[query(pos[x], pos[y])] << "\n";
  }

  return 0;
}