Cod sursa(job #581241)

Utilizator miticaMitica mitica Data 13 aprilie 2011 22:20:14
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

const int maxn = 100005;

int arb[maxn << 4],n,m,i,k,a,b,s,f,x,poz,sol,L[maxn << 1],H[maxn << 1],First[maxn];
vector <int> G[maxn];

void update(int nod, int st, int dr)
{
    int mij;
    if (st==dr)
    {
        arb[nod]=st;
        return;
    }
    mij=(st+dr)/2;
    update(2*nod, st, mij);
    update(2*nod+1, mij+1, dr);

    if (L[arb[2*nod]] <= L[arb[2*nod+1]])
        arb[nod]=arb[2*nod];
    else
        arb[nod]=arb[2*nod+1];
}

void query(int nod, int st, int dr)
{
    int mij;
    if (s<=st && dr<=f)
    {
        if (sol>L[arb[nod]])
        {
            sol=L[arb[nod]];
            poz=H[arb[nod]];
        }
        return;
    }
    mij=(st+dr)/2;
    if (s<=mij)
        query(2*nod, st, mij);
    if (mij<f)
        query(2*nod+1, mij+1, dr);
}

void df(int x, int nv)
{
    H[++k]=x;
    L[k]=nv;
    First[x]=k;

    vector <int>::iterator it;
    for (it=G[x].begin(); it!=G[x].end(); ++it)
    {
        df(*it, nv+1);

        H[++k]=x;
        L[k]=nv;
    }
}

int lca(int x, int y)
{
    s=First[x]; f=First[y];
    if (s>f) swap(s,f);
    query(1,1,k);

    return poz;
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d %d", &n, &m);
    for (i=1; i<n; i++)
    {
        scanf("%d", &x);
        G[x].push_back(i+1);
    }
    k=0;
    df(1,0);
    update(1,1,k);

    for (i=1; i<=m; i++)
    {
        scanf("%d %d", &a, &b);
        poz=sol=int(2e9);
        printf("%d\n", lca(a,b));
    }

    return 0;
}