Cod sursa(job #1090639)

Utilizator lianaliana tucar liana Data 22 ianuarie 2014 21:37:59
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.77 kb
#include<stdio.h>
#include<vector>
using namespace std;
#define nmax 100005
struct element{long n, h;};
int v[4*nmax], h[nmax], prpoz[nmax];
element mini[nmax];
int i, n, a, b, m, hac, ne, poz, t, x, aux;
element rez;
vector <int> ma[nmax];

void dfs(int x)
{
    vector <int> ::iterator it;
    v[++ne]=x;
    if (prpoz[x]==0)
        prpoz[x]=ne;
    hac++;  h[x]=hac;
    for (it=ma[x].begin();it!=ma[x].end();it++)
    {
        dfs(*it);
        v[++ne]=x;
    }
    hac--;
}

void update(int st, int dr, int nod)
{
    if (st==dr)
    {   mini[nod].h=h[x];  mini[nod].n=x;   }
    else
    {
        int mjc=(st+dr)/2;
        if (poz<=mjc)
            update(st,mjc,2*nod);
        else
            update(mjc+1,dr,2*nod+1);
        if (mini[2*nod].h<mini[2*nod+1].h)
            mini[nod]=mini[2*nod];
        else
            mini[nod]=mini[2*nod+1];
    }
}

void query(int st, int dr, int nod)
{
    if ((a<=st)&&(dr<=b))
    {
        if ((rez.h>mini[nod].h) || (rez.h==0))
            rez=mini[nod];
    }
    else
    {
        int mjc=(st+dr)/2;
        if (a<=mjc)
            query(st,mjc,2*nod);
        if (b>=mjc+1)
            query(mjc+1,dr,2*nod+1);
    }
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%ld %ld",&n,&m);
    for (i=2;i<=n;i++)
    {
        scanf("%ld",&t);
        ma[t].push_back(i);
    }

    dfs(1);

    for (i=1;i<=ne;i++)
    {
        poz=i;  x=v[i];
        update(1,ne,1);
    }
    for (i=1;i<=m;i++)
    {
        scanf("%ld %ld",&a,&b);
        a=prpoz[a];   b=prpoz[b];   rez.h=0;
        if (a>b)
        {   aux=a;  a=b;    b=aux;        }
        query(1,ne,1);
        printf("%ld\n",rez.n);
    }
    return 0;
}