Cod sursa(job #1141055)

Utilizator heracleRadu Muntean heracle Data 12 martie 2014 15:55:20
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.79 kb
#include <cstdio>
#include <vector>

const int Q=100006;

std::vector<int> fiu[Q+1];

int n,q;

int tat[Q+1];

int euler[3*Q+16],ne,st[Q+1],nivel[Q+1];
int niv=0;
int r[18][3*Q+16] ,log[3*Q+16];


void dfs(int x)
{
    euler[++ne]=x;
    st[x]=ne;
    nivel[x]=niv;
   // r[0][ne]=euler[ne];
    niv++;
    for(int i=0; i<fiu[x].size(); i++)
    {
        dfs(fiu[x][i]);
        euler[++ne]=x;
        //r[0][ne]=euler[ne];
    }
    niv--;
}



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

    scanf("%d%d",&n,&q);

    for(int i=2; i<=n; i++)
    {
        scanf("%d",&tat[i]);
        fiu[tat[i]].push_back(i);
    }
/*
    for(int i=1; i<=n; i++)
    {
        printf("%d\t",i);
        for(int j=0; j<fiu[i].size() ; j++)
            printf("%d ",fiu[i][j]);
        printf("\n");
    }
*/
    dfs(1);
/*
    for(int i=1; i<=en; i++)
    {
        r[i][0]=nivel[e[i]];
        for(int j=1; (1<<j) +i <=en; j++)
        {

        }
    }
*/
    r[0][1]=euler[1];
    for(int i=2; i<=ne; i++)
    {
        log[i]=log[i/2]+1;
        r[0][i]=euler[i];
    }


    for(int p=1; (1<<p)<=ne; p++)
    {
        for(int st=1; st+(1<<p)<=ne; st++)
        {
            if(nivel[ r[p-1][st] ]  < nivel[ r[p-1][st+(1<<(p-1))]  ])
                r[p][st]=r[p-1][st];
            else
                r[p][st]=r[p-1][st+(1<<(p-1))];
        }
    }
    int a,b,dif;
    for(int i=1; i<=q; i++)
    {
        scanf("%d%d",&a,&b);
        a=st[a];
        b=st[b];
        dif=b-a+1;
        dif=log[dif];

        if(nivel[r[dif][a]] <nivel[ r[dif][b-(1<<dif)+1]]  )
            printf("%d\n", r[dif][a]);
        else
            printf("%d\n",r[dif][b-(1<<dif)+1] );

    }

    return 0;
}