Cod sursa(job #897277)

Utilizator the@EyE@Postavaru Stefan the@EyE@ Data 27 februarie 2013 19:43:29
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.57 kb
#include<cstdio>
#include<vector>
#include<algorithm>
#define INF 100005

using namespace std;

int n,m,d[18][INF][2],first[INF],lg[INF];
vector<int> arb[INF];
vector< pair<int,int> > v;

void eul(int nod,int lv)
{
    v.push_back(make_pair(lv,nod));
    if(first[nod]==0)first[nod]=v.size()-1;
    for(int i=0;i<arb[nod].size();++i)
    {
        int nod2=arb[nod][i];
        eul(nod2,lv+1);
        v.push_back(make_pair(lv,nod));
    }
}

void assign(int x[2],pair<int,int> y)
{
    x[0]=y.first;
    x[1]=y.second;
}

void getMin(int x[2],int y[2],int z[2])
{
    if(y[0]<z[0]){x[0]=y[0];x[1]=y[1];}
    else {x[0]=z[0];x[1]=z[1];}
}

void rmq()
{
    n=v.size();

    lg[1]=0;
    for(int i=2;i<=n;++i)lg[i]=lg[i/2]+1;

    for(int i=0;i<v.size();++i)assign(d[0][i],v[i]);

    for(int i=1;i<=lg[n];++i)
        for(int j=0;j<n-(1<<i)+1;++j)
            getMin(d[i][j],d[i-1][j],d[i-1][j+(1<<(i-1))]);
}

int querry(int a,int b)
{
    int p1=min(first[a],first[b]);
    int p2=max(first[a],first[b]);
    int k=lg[p2-p1+1];
   // return min(d[k][a],d[k][b-(1<<k)+1]);
   int x[2];
   getMin(x,d[k][p1],d[k][p2-(1<<k)+1]);
   return x[1];
}

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

    scanf("%d%d",&n,&m);
    for(int i=1;i<n;++i)
    {
        int x;
        scanf("%d",&x);
        arb[x].push_back(i+1);
    }
    eul(1,0);
    rmq();
    for(int i=0;i<m;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        printf("%d\n",querry(a,b));
    }
    return 0;
}