Cod sursa(job #1696379)

Utilizator TibiraducanuTiberiu Raducanu Tibiraducanu Data 28 aprilie 2016 22:59:08
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.7 kb
#include <cstdio>
#include <vector>
using namespace std;

const int NMAX=100005;
const int Roxi=2000005;
vector <int> G[NMAX];

int Euler[Roxi],First[NMAX],Rmq[Roxi][21],Lev[Roxi],Lg[Roxi],cnt;

void dfs(int x,int niv)
{
    cnt++;
    Euler[cnt]=x;
    Lev[cnt]=niv;
    First[x]=cnt;

    for(int i=0;i<(int)G[x].size();i++)
    {
        int y=G[x][i];

        dfs(y,niv+1);

        cnt++;
        Euler[cnt]=x;
        Lev[cnt]=niv;
    }
}

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

    int n,m,i,j,x,y,k,l,lg,a,b;

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

    for(i=2;i<=n;i++)
    {
        scanf("%d",&x);
        G[x].push_back(i);
    }

    dfs(1,0);

    for(i=2;i<=cnt;i++)
        Lg[i]=Lg[i/2]+1;

    for(i=1;i<=cnt;i++)
    {
        for(j=0;(1<<j)<=i;j++)
        {
            if(j==0)
            {
                Rmq[i][0]=i;
                continue;
            }

            k=i-(1<<(j-1));

            if(Lev[Rmq[i][j-1]]<=Lev[Rmq[k][j-1]]) Rmq[i][j]=Rmq[i][j-1];
            else Rmq[i][j]=Rmq[k][j-1];
        }
    }

    /*for(i=1;i<=cnt;i++)
    {
        for(j=0;(1<<j)<=i;j++)
        {
           printf("%d ",Rmq[i][j]);
        }
        printf("\n");
    }*/

    //for(i=1;i<=n;i++) printf("%d ",First[i]);

    for(i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);

        a=First[x];
        b=First[y];

        if(a>b) swap(a,b);

        l=b-a+1;
        lg=Lg[l];

        //printf("%d %d\n",lg,l);

        if(Lev[Rmq[b][lg]]<Lev[Rmq[a+(1<<lg)-1][lg]]) printf("%d\n",Euler[Rmq[b][lg]]);
        else printf("%d\n",Euler[Rmq[a+(1<<lg)-1][lg]]);
    }

    return 0;
}