Cod sursa(job #1184890)

Utilizator chiriacandrei25Chiriac Andrei chiriacandrei25 Data 14 mai 2014 14:17:18
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb
#include <cstdio>
#include <vector>
#define Nmax 100005

using namespace std;

vector <int> L[Nmax];
int st[2*Nmax],N,M,len,niv[2*Nmax],dp[2*Nmax][20],t[2*Nmax],poz[Nmax];
bool viz[Nmax];

inline void Dfs(int nod, int nivel)
{
    viz[nod]=true;
    st[++len]=nod;
    niv[len]=nivel;
    poz[nod]=len;
    vector <int>::iterator it;
    for(it=L[nod].begin();it!=L[nod].end();++it)
        if(!viz[*it])
        {
            Dfs(*it,nivel+1);
            st[++len]=nod;
            niv[len]=nivel;
            poz[nod]=len;
        }
}

inline void RMQ()
{
    int i,j;
    for(i=1;i<=len;++i)
        dp[i][0]=i;
    for(i=1;i<=len;++i)
        for(j=1;j<=20 && (1<<j)<=i;++j)
            if(niv[dp[i][j-1]]<niv[dp[i-(1<<(j-1))][j-1]])
                dp[i][j]=dp[i][j-1];
            else
                dp[i][j]=dp[i-(1<<(j-1))][j-1];
}

inline void PreCalcul()
{
    t[1]=0;
    for(int i=2;i<=200000;++i)
    {
        t[i]=t[i-1];
        if((1<<(t[i]+1))<=i)
            ++t[i];
    }
}

int main()
{
    int i,x,y,r,p,aux;
    freopen ("lca.in","r",stdin);
    freopen ("lca.out","w",stdout);
    scanf("%d%d", &N,&M);
    for(i=2;i<=N;++i)
    {
        scanf("%d", &x);
        L[i].push_back(x);
        L[x].push_back(i);
    }
    Dfs(1,0);
    RMQ();
    PreCalcul();
    while(M--)
    {
        scanf("%d%d", &x,&y);
        x=poz[x]; y=poz[y];
        if(x>y)
        {
            aux=x; x=y; y=aux;
        }
        r=t[y-x+1];
        p=(1<<r);
        if(niv[dp[y][r]]<niv[dp[x+p-1][r]])
            printf("%d\n", st[dp[y][r]]);
        else
            printf("%d\n", st[dp[x+p-1][r]]);
    }
    return 0;
}