Cod sursa(job #2087648)

Utilizator tziplea_stefanTiplea Stefan tziplea_stefan Data 13 decembrie 2017 21:51:56
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.76 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];

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()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    scanf("%d %d", &N, &Q);
    for (i=2; i<=N; i++)
    {
        scanf("%d", &F);
        G[F].push_back(i);
    }
    DFS(1, 1);
    Initialize(1, 1, M);
    for (i=1; i<=Q; i++)
    {
        scanf("%d %d", &A, &B);
        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;
}