Cod sursa(job #2273134)

Utilizator andreiomd1Onut Andrei andreiomd1 Data 31 octombrie 2018 08:35:09
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.37 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX=1e6+6;

vector <int> G[NMAX];

bitset <NMAX> Pus;

vector <pair <int, int> >A;

int N, M, i, X, position[NMAX], u, v, nn, solmax=INT_MAX, solafis;

int Arbore[5*NMAX], Arbore2[5*NMAX];

map <int, vector <int> > Mp;

void DFS (int Nod, int Nivel)
{
    Pus.set(Nod);

    A.push_back({Nod, Nivel});

    if(!position[Nod])
        position[Nod]=A.size()-1;

    for(int i=0; i<G[Nod].size(); i++)
        if(Pus[G[Nod][i]]==0)
        {
            Pus.set(G[Nod][i]);

            DFS(G[Nod][i], Nivel+1);

            A.push_back({Nod, Nivel});
        }
}

void Update (int nod, int a, int b, int poz, int val)
{
    if(a==b)
    {
        Arbore[nod]=val;
        Arbore2[nod]=A[poz-1].first;
        return;
    }

    int mij=(a+b)/2;

    if(poz<=mij)
        Update(2*nod, a, mij, poz, val);
    if(poz>mij)
        Update(2*nod+1, mij+1, b, poz, val);

    if(Arbore[2*nod]<Arbore[2*nod+1])
    {
        Arbore[nod]=Arbore[2*nod];
        Arbore2[nod]=Arbore2[2*nod];
    }
    else
    {
        Arbore[nod]=Arbore[2*nod+1];
        Arbore2[nod]=Arbore2[2*nod+1];
    }
}

int Query (int nod, int a, int b, int qa, int qb)
{
    if(qa<=a && b<=qb)
    {
        if(Arbore[nod]<solmax)
        {
            solmax=Arbore[nod];

            solafis=Arbore2[nod];
        }

        return Arbore[nod];
    }

    int mij=(a+b)/2;

    int ans1=INT_MAX, ans2=INT_MAX;

    if(qa<=mij)
        ans1=Query(2*nod, a, mij, qa, qb);
    if(qb>mij)
        ans2=Query(2*nod+1, mij+1, b, qa, qb);

    return min(ans1, ans2);
}

int solve (int u, int v)
{
    int i=position[u];
    int j=position[v];

    if(i==j)
        return A[i].first;

    if(i>j)
        swap(i, j);

    i++;
    j++;

    solmax=solafis=INT_MAX;

    int ans=Query(1, 1, 2*N-1, i, j);

    return solafis;
}

int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

    scanf("%d%d", &N, &M);

    for(i=2; i<=N; i++)
    {
        scanf("%d", &X);

        G[X].push_back(i);
    }

    DFS(1, 1);

    A.pop_back();

    for(i=1; i<=2*N-1; i++)
        Update(1, 1, 2*N-1, i, A[i-1].second);

    for(i=1; i<=M; i++)
    {
        scanf("%d%d", &u, &v);

        printf("%d\n", solve(u, v));
    }

    return 0;
}