Cod sursa(job #2437953)

Utilizator AlexNeaguAlexandru AlexNeagu Data 10 iulie 2019 20:05:27
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.07 kb
#include<bits/stdc++.h>
#pragma gcc optimize("O3")
#define all(s) s.begin(),s.end()
#define rc(x) return cout<<x<<endl,0
#define forn(i,n) for(int i=0;i<int(n);i++)
#define len(a) (int) (a).size()
#define pb push_back
#define mp make_pair
#define fr first
#define sc second
#define nmax 100005
typedef long long ll;
typedef long double ld;
const int mod=1e9+7;
const ll inf=0x3f3f3f3f3f3f3f3f;
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector < int > E[nmax << 1], Ind_First(nmax << 1, 0), Log(nmax << 1, 0);
vector < pair < int, int > > Euler_Tour(nmax << 1);
int RMQ[20][nmax << 2], K = 0, n, m;
void Dfs(int node, int level)
{
    Euler_Tour[++K].fr = node;
    Euler_Tour[K].sc = level;
    Ind_First[node] = K;
    for (auto it : E[node])
    {
        Dfs(it, level + 1);
        Euler_Tour[++K].fr = node;
        Euler_Tour[K].sc = level;
    }
}
void Range_Minimum_Query()
{
    for (int i = 2; i <= K; i++)
        Log[i] = Log[i / 2] + 1;
    for (int i = 1; i <= K; i++)
        RMQ[0][i] = i;
    for (int i = 1; (1 << i) <= K; i++)
        for (int j = 1; j <= K - (1 << i); j++)
    {
        int l = 1 << (i - 1);
        RMQ[i][j] = RMQ[i - 1][j];
        int y = Euler_Tour[RMQ[i - 1][j + l]].sc;
        if (y < Euler_Tour[RMQ[i][j]].sc) RMQ[i][j] = RMQ[i - 1][j + l];

    }
}
int LCA(int x, int y)
{
    int a = Ind_First[x];
    int b = Ind_First[y];
    if (a > b) swap(a, b);
    int d = b - a + 1;
    int l = Log[d];
    int x1 = d - (1 << l);;
    int position = RMQ[l][a];
    if (Euler_Tour[RMQ[l][a + x1]].sc < Euler_Tour[RMQ[l][a]].sc)
        position = RMQ[l][a + x1];
    return Euler_Tour[position].fr;
}
int main()
{
  //freopen("input.txt","r",stdin);
  //freopen("output.txt","w",stdout);
  ios_base::sync_with_stdio(0); cin.tie(0);
  fin >> n >> m;
  for (int i = 2; i <= n; i++)
  {
      int x;
      fin >> x;
      E[x].pb(i);
  }
  Dfs(1, 0);
  Range_Minimum_Query();
  while (m--)
  {
      int x, y;
      fin >> x >> y;
      fout << LCA(x, y) << "\n";
  }
}