Cod sursa(job #2635262)

Utilizator k2e0e0w3qDumitrescu Gheorghe k2e0e0w3q Data 13 iulie 2020 20:08:42
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.51 kb
#include <bits/stdc++.h>
#define N 100000
#define _log(x) 31-__builtin_clz(x)
using namespace std;

int first[N<<1], niv[N<<1], seg[_log(N)+2][N<<1], v[(N<<1)+1], size;
struct nod {
  int inf;
  struct nod* urm;
} *G[N+1];

void add (int x, int i) {
  struct nod *e = (struct nod*) malloc(sizeof (struct nod));
  e->inf = i;
  e->urm = G[x];

  G[x] = e;
}

void dfs (int x, int from) {
  v[size++] = x;

  for (; G[x]; G[x]=G[x]->urm) {
      first[G[x]->inf] = size;
      dfs(G[x]->inf, x);
    }
  v[size++] = from;
}

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

    int n, i, q, x, y;
    fin >> n >> q;
    for (i=2; i<=n; i++) {
        fin >> x;
        niv[i]=niv[x]+1;
        add(x, i);
    }

    dfs(1, 0);
    n = size;

    int j;
    for (i=0; i<n; ++i)
        seg[0][i]=i;

    for (i=1; (1<<i)<n; i++)
        for (j=0; j+(1<<i)<=n; j++) {
            int can1=seg[i-1][j],
                can2=seg[i-1][j+(1<<i-1)];
            if (niv[v[can1]]<niv[v[can2]])
                seg[i][j]=can1;
            else
                seg[i][j]=can2;
        }


    for (; q; q--) {
        fin >> x >> y;
        x=first[x];
        y=first[y];
        if (x>y) i=x, x=y, y=i;
        int lg=_log(y-x+1),
            can1=seg[lg][x],
            can2=seg[lg][y-(1<<lg)+1];
        if (niv[v[can1]]<niv[v[can2]])
            fout << v[can1];
        else
            fout << v[can2];
        fout << '\n';
    }
    return 0;
}