Cod sursa(job #1499866)

Utilizator UMihneaUngureanu Mihnea UMihnea Data 11 octombrie 2015 11:29:21
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.18 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#define N 100010

using namespace std;

vector<int> v[N];
int tata[N], niv[N], prim[N], rmq[18][2*N], n, m, i, j, x, k, y, L, R, p;
void df(int);

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(i=2;i<=n;i++)
    {
        scanf("%d",&tata[i]);
        v[tata[i]].push_back(i);
    }
    df(1);
    for(i=1;i<=17;i++)
    {
        R = 1<<i;
        p = R>>1;
        for(L=1;R<=k;R++,L++)
        {
            x = rmq[i-1][L];
            y = rmq[i-1][L+p];
            rmq[i][L] = niv[x]<niv[y]?x:y;
        }
    }
    for(;m;m--)
    {
        scanf("%d%d",&x,&y);
        x = prim[x];
        y = prim[y];
        if(x>y)swap(x,y);
        i = (int)log2((double)(y-x+1)+0.00001);
        j = 1<<i;
        x = rmq[i][x];
        y = rmq[i][y-j+1];
        x = niv[x]<niv[y]?x:y;
        printf("%d\n",x);
    }
    return 0;
}
void df(int nod)
{
    niv[nod] = niv[tata[nod]]+1;
    rmq[0][++k] = nod;
    prim[nod] = k;
    for(auto vec:v[nod])
    {
        df(vec);
        rmq[0][++k] = nod;
    }
}