Cod sursa(job #1970121)

Utilizator DenisONIcBanu Denis Andrei DenisONIc Data 18 aprilie 2017 21:56:13
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.49 kb
#include <fstream>
#include <cstdio>
#include <vector>
#include <cmath>
#define pb push_back
#define Nmax 100001
using namespace std;

ofstream g("lca.out");

int n,q,x,fst[Nmax];
bool uz[Nmax];
vector<int> V[Nmax];

pair<int,int> rmq[21][Nmax*4];
vector<pair<int,int> > E;

void dfs(int nod,int niv)
{
    E.pb(make_pair(nod,niv));
    fst[nod] = E.size();
    for (int i=0;i<V[nod].size();i++)
    {
        if (!uz[V[nod][i]])
        {
            dfs(V[nod][i],niv+1);
            E.pb(make_pair(nod,niv));
        }
    }
}

int lca(int a,int b)
{
    a = fst[a];
    b = fst[b];
    if (a>b)
        swap(a,b);
    int lg = log2(b-a+1);

    if (rmq[lg][a].second<rmq[lg][b-(1<<lg)+1].second)
        return rmq[lg][a].first;
    return rmq[lg][b-(1<<lg)+1].first;
}

int main()
{
    freopen("lca.in","r",stdin);
    scanf("%d%d",&n,&q);
    for (int i=2;i<=n;i++)
    {
        scanf("%d",&x);
        V[x].pb(i);
    }

    dfs(1,1);

    int mx = log2(E.size());
    for (int i=1;i<=E.size();i++)
        rmq[0][i] = E[i-1];

    for (int i=1;i<mx;i++)
    {
        for (int j=1;j<=(E.size()-(1<<i))+1;j++)
        {
            if (rmq[i-1][j].second<rmq[i-1][j+(1<<(i-1))].second)
                rmq[i][j] = rmq[i-1][j];
            else
                rmq[i][j] = rmq[i-1][j+(1<<(i-1))];
        }
    }

    for (int i=1;i<=q;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        g<<lca(a,b)<<'\n';
    }
    return 0;
}