Cod sursa(job #1137439)

Utilizator Pintilie_AndreiFII-Pintilie Andrei Pintilie_Andrei Data 9 martie 2014 12:55:35
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.86 kb
#include <cstdio>
#include <vector>
#define mp make_pair
#define PII pair<int,int>
#define N 100003
using namespace std;
vector <int> tree[N];
vector <PII> peuler;
int poz[2*N],rmq[2*N][18],lg2[2*N];
int n,m,k;
void R()
{
    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);
        tree[x].push_back(i);
    }
    peuler.push_back(mp(0,0));

}

void Euler( int nod,int niv)
{
    poz[nod]=++k;
    peuler.push_back(mp(nod,niv));
    vector <int>::iterator it;
    for(it=tree[nod].begin(); it!=tree[nod].end(); it++)
    {
//printf("%d ",*it);
        Euler(*it,niv+1);
        peuler.push_back(mp(nod,niv));
        k++;
    }
}

void createRMQ()
{
    int i,j,p1,p2;
    for(i=1; i<=k; i++)
        rmq[i][0]=i;
        lg2[1]=0;
    for(i=2; i<=k; i++)
          lg2[i]=lg2[i>>1]+1;

    for(j=1; (1<<j)<=k; j++)
        for(i=1; i+(1<<(j-1))<=k; i++)
    {
        p1=rmq[i][j-1];
        p2=rmq[i+(1<<(j-1))][j-1];
        if(peuler[p1].second < peuler[p2].second)
            rmq[i][j]=p1;
        else
            rmq[i][j]=p2;
    }


}
// 1<<n   n^2
// n>>1   log2 n
//  n<<1  m*2
int Answer(int x,int y)
{
    int d,lg,p1,p2;
    d=y-x+1;
    lg=lg2[d];
    p1=rmq[x][lg];
    p2=rmq[x+d-(1<<lg)][lg];
    if(peuler[p1].second<peuler[p2].second)
        return peuler[p1].first ;
        return peuler[p2].first ;
}

void Quest()
{
    int i,x,y,aux;
    for(i=1; i<=m; i++)
    {
        scanf("%d %d",&x,&y);
        if(poz[y]<poz[x])
        {
            aux=x;
            x=y;
            y=aux;
        }
        printf("%d\n",Answer(poz[x],poz[y]));
    }
}

int main()
{
    R();
    Euler(1,0);
    createRMQ();
    Quest();
   // printf("%d",Answer(1,7));
    return 0;
}