Cod sursa(job #1276900)

Utilizator chiriacandrei25Chiriac Andrei chiriacandrei25 Data 26 noiembrie 2014 22:59:30
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.47 kb
#include <cstdio>
#include <vector>
#define Nmax 200005

using namespace std;

int n,top,poz[Nmax],nivel[Nmax],st[Nmax],dp[Nmax][20],lg[Nmax];
vector <int> L[Nmax];

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

inline void RMQ()
{
    int i,j;
    for(i=1;i<=n;++i) dp[i][0]=i;
    for(j=1;j<=20;++j)
        for(i=n;i;--i)
        {
            if(i+(1<<j)-1>n) continue;
            if(nivel[st[dp[i][j-1]]]<nivel[st[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 Prec()
{
    int i;
    lg[1]=0;
    for(i=2;i<=n;++i)
        lg[i]=lg[i/2]+1;
}

inline int Query(int x, int y)
{
    int l=y-x+1,p,t;
    p=lg[l]; t=(1<<p);
    if(nivel[st[dp[x][p]]]<nivel[st[dp[y+1-t][p]]]) return st[dp[x][p]];
    return st[dp[y+1-t][p]];
}

int main()
{
    int i,x,y,m;
    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[x].push_back(i);
    }
    Dfs(1,1);
    n=top;
    Prec();
    RMQ();
    while(m--)
    {
        scanf("%d%d", &x,&y);
        x=poz[x]; y=poz[y];
        printf("%d\n", Query(min(x,y),max(x,y)));
    }
    return 0;
}