Cod sursa(job #2294698)

Utilizator Cojocaru_Andrei_CristianCojocaru Andrei Cristian Cojocaru_Andrei_Cristian Data 2 decembrie 2018 18:21:18
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.24 kb
#include <bits/stdc++.h>

using namespace std;
int n, q, m, x, y;
int depth[300005], p[300005], v[300005], log1[300005];
int rmq[200005][20];
vector <int> g[300005];
void dfs(int nod, int cnt)
{
  depth[nod] = cnt;
  v[++m] = nod;
  for(auto i : g[nod])
  {
    dfs(i,cnt + 1);
    v[++m]=nod;
  }
}
int findmin(int l, int r)
{
  int d=r-l+1,lg=log1[d];
  if(depth[rmq[l][lg]]>depth[rmq[r-(1<<lg)+1][lg]])
    return rmq[r-(1<<lg)+1][lg];
  return rmq[l][lg];
}
int main()
{
  ifstream cin ("lca.in");
  ofstream cout ("lca.out");
  cin>>n>>q;
  for(int i=1;i<n;i++)
  {
    cin>>x;
    g[x].push_back(i + 1);
  }
  dfs(1, 1);
  for(int i=1;i<=m;i++)
  {
    if(!p[v[i]])
      p[v[i]] = i;
  }
  rmq[1][0] = v[1];
  for(int i = 2; i <= m; i++)
  {
    log1[i] = log1[i / 2] + 1;
    rmq[i][0] = v[i];
  }
  for(int j = 1; (1 << j) <= m; j++)
    for(int i = 1; i <= m - (1 << j) + 1; i++)
    {
      rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
      if(depth[rmq[i + (1 << (j - 1))][j - 1]] > depth[rmq[i][j - 1]])
        rmq[i][j] = rmq[i][j - 1];
    }
  for(int i=1;i<=q;i++)
{
    cin>>x>>y;
    x=p[x];
    y=p[y];
    if(x > y)
      swap(x,y);
    cout<<findmin(x,y)<<"\n";
  }
  return 0;
}