Cod sursa(job #867384)

Utilizator raulstoinStoin Raul raulstoin Data 29 ianuarie 2013 17:32:59
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.51 kb
#include<cstdio>
#include<vector>
#define nmax 100005
using namespace std;
int n,m,a[2*nmax],rmq[18][nmax],l,ind[nmax],nivel[nmax],power[nmax],level[nmax];
bool use[nmax];
vector<int> G[nmax];
void DFS(int nod,int niv)
{
    vector<int> :: iterator it;
    a[++l]=nod;
    level[l]=niv;
    ind[nod]=l;
    for(it=G[nod].begin();it!=G[nod].end();it++)
    {
        DFS(*it,niv+1);
        a[++l]=nod;
        level[l]=niv;
    }
}
void rmq_build()
{
    int i,j,k;
    for(i=2;i<=l;i++)
        power[i]=power[i/2]+1;
    for(i=1;i<=l;i++)
        rmq[0][i]=i;
    for(i=1;(1<<i)<l;i++)
        for(j=1;j<=l-(1<<i);j++)
        {
            k=1<<(i-1);
            if(level[rmq[i-1][j + k]]<level[rmq[i-1][j]])
                rmq[i][j]=rmq[i-1][j + k];
            else
                rmq[i][j]=rmq[i-1][j];
        }
}
void solve()
{
    int x,y,dif,i,plus,sol;
    while(m--)
    {
        scanf("%d %d",&x,&y);
        x=ind[x];
        y=ind[y];
        if(x>y)
            swap(x,y);
        dif=y-x+1;
        i=power[dif];
        sol=rmq[i][x];
        plus=dif-(1<<i);
        if(level[rmq[i][x]]>level[rmq[i][x+plus]])
            sol=rmq[i][x+plus];
        printf("%d\n",a[sol]);
    }
}
int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d %d",&n,&m);
    int x;
    for(int i=2;i<=n;i++)
    {
        scanf("%d",&x);
        G[x].push_back(i);
    }
    DFS(1,0);
    rmq_build();
    solve();
    return 0;
}