Cod sursa(job #1892715)

Utilizator delia_99Delia Draghici delia_99 Data 25 februarie 2017 11:08:41
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.57 kb
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

const int NMAX=1e5;

int n,m,i,crt;
int first[NMAX+5],lg[NMAX*2+5];
vector <int> G[NMAX+5];
vector <pair <int,int> > D[18];

void euler(int node,int lvl)
{
    int i,s=G[node].size();

    D[0].push_back(make_pair(node,lvl));
    ++crt;
    first[node]=crt;

    for(i=0; i<s; ++i)
    {
        euler(G[node][i],lvl+1);
        D[0].push_back(make_pair(node,lvl));
        ++crt;
    }
}

void rmq()
{
    int i,j;

    for(i=2; i<=crt; ++i)
        lg[i]=lg[i/2]+1;

    for(i=1; i<=lg[crt]; ++i)
    {
        D[i].push_back(make_pair(0,0));
        for(j=1; j<=crt-(1<<i)+1; ++j)
        {
            D[i].push_back(make_pair(0,0));
            if(D[i-1][j].second<D[i-1][j+(1<<(i-1))].second)
                D[i][j]=D[i-1][j];
            else D[i][j]=D[i-1][j+(1<<(i-1))];
        }
    }

}

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

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

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

    D[0].push_back(make_pair(0,0));
    euler(1,1);
    rmq();

    while(m--)
    {
        int x,y,k;
        scanf("%d%d",&x,&y);

        if(first[x]>first[y])
            swap(x,y);

        k=lg[first[y]-first[x]+1];

        if(D[k][first[x]].second<D[k][first[y]-(1<<k)+1].second)
            printf("%d\n",D[k][first[x]].first);
        else printf("%d\n",D[k][first[y]-(1<<k)+1].first);
    }

    return 0;
}