Cod sursa(job #2087655)

Utilizator tziplea_stefanTiplea Stefan tziplea_stefan Data 13 decembrie 2017 22:00:45
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.14 kb
#include <fstream>
#include <cstdio>
#include <vector>
#define VAL 100005
#define EUL 200005
#define ARB 524295

using namespace std;

int N, M, Q, i, j, F;
int niv[VAL], E[EUL];
int first[VAL], last[VAL];
int mn, ANS, arb[ARB], A, B;
vector <int> G[VAL];

char buff[VAL];
int poz=0;

int citire()
{
    int nr=0;
    while (buff[poz]<'0' || buff[poz]>'9')
      if (++poz==VAL)
        fread(buff, 1, VAL, stdin), poz=0;
    while ('0'<=buff[poz] && buff[poz]<='9')
    {
        nr=nr*10+buff[poz]-'0';
        if (++poz==VAL)
          fread(buff, 1, VAL, stdin), poz=0;
    }
    return nr;
}

void DFS(int nod, int level)
{
    vector <int> :: iterator it;
    niv[nod]=level;
    E[++M]=nod;
    if (first[nod]==0)
      first[nod]=M;
    last[nod]=M;
    for (it=G[nod].begin(); it!=G[nod].end(); it++)
    {
        DFS(*it, level+1);
        E[++M]=nod;
        last[nod]=M;
    }
}

void Initialize(int nod, int be, int en)
{
    if (be==en)
      arb[nod]=E[be];
    else
    {
        int mid=(be+en) / 2;
        Initialize(2*nod, be, mid);
        Initialize(2*nod+1, mid+1, en);
        if (niv[arb[2*nod]]<niv[arb[2*nod+1]])
          arb[nod]=arb[2*nod];
        else
          arb[nod]=arb[2*nod+1];
    }
}

void Query(int nod, int be, int en, int st, int dr)
{
    if (st<=be && en<=dr)
    {
        if (mn>niv[arb[nod]])
        {
            mn=niv[arb[nod]];
            ANS=arb[nod];
        }
        return;
    }
    int mid=(be+en) / 2;
    if (max(be, st)<=min(mid, dr))
      Query(2*nod, be, mid, st, dr);
    if (max(mid+1, st)<=min(en, dr))
      Query(2*nod+1, mid+1, en, st, dr);
}

int main()
{
    std::ios::sync_with_stdio(false);
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    N=citire();
    Q=citire();
    for (i=2; i<=N; i++)
    {
        F=citire();
        G[F].push_back(i);
    }
    DFS(1, 1);
    Initialize(1, 1, M);
    for (i=1; i<=Q; i++)
    {
        A=citire();
        B=citire();
        mn=N*100;
        ANS=0;
        if (first[A]<=last[B])
          Query(1, 1, M, first[A], last[B]);
        else
          Query(1, 1, M, first[B], last[A]);
        printf("%d\n", ANS);
    }
    return 0;
}