Cod sursa(job #1257489)

Utilizator j.loves_rockJessica Joanne Patrascu j.loves_rock Data 7 noiembrie 2014 20:22:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.48 kb
#include<cstdio>
#include<vector>

using namespace std;

vector<int> a[1000002];
int y,niv[200003],i,n,m,x,nr,rmq[21][400002],elr[200002],ap[100002],lg[200003];


void rmy()
{
    for(int i=2; i<=nr; ++i)
        lg[i]=lg[i >> 1]+1;
    for(int i=1; i<=nr; ++i)
        rmq[0][i]=i;
    for(int i=1; (1 << i)<nr; ++i)
        for(int j=1; j<=nr-(1 << i); ++j)
        {
            int l=1 << (i - 1);
            rmq[i][j]=rmq[i-1][j];
            if(niv[rmq[i-1][j + l]]<niv[rmq[i][j]])
                rmq[i][j]=rmq[i-1][j + l];
        }
}

int lca(int x,int y)
{
    int a,b,dif,q,l,sol;
        a=ap[x];  b=ap[y];
        if (a>b)
        {
            dif=a;
            a=b;
            b=dif;
        }
        dif=b-a+1;
        l=lg[dif];
    sol=rmq[l][a];
    q=dif-(1 << l);
    if(niv[sol]>niv[rmq[l][a+q]])
                sol=rmq[l][a+q];
    return elr[sol];
}

void euler(int nod,int lev)
{
    int i;
    elr[++nr]=nod;
    niv[nr]=lev;
    ap[nod]=nr;
    for (i=0;i<a[nod].size();i++)
    {
        euler(a[nod][i],lev+1);
        elr[++nr]=nod;
        niv[nr]=lev;
    }
}
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);
        a[x].push_back(i+1);
    }
    nr=0;
    euler(1,0);
    rmy();
    for (i=1;i<=m;i++)
    {
        scanf("%d %d",&x,&y);
        printf("%d\n",lca(x,y));
    }
    return 0;
}