Cod sursa(job #2105916)

Utilizator xRoALexBirtoiu Alexandru xRoALex Data 14 ianuarie 2018 17:03:16
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.43 kb
#include <cstdio>
#include <vector>
#define Nmax 100005
using namespace std;

FILE * in=fopen("lca.in","r");
FILE * out=fopen("lca.out","w");

int n,m,k;
int L[2*Nmax],H[2*Nmax],ap[Nmax],lg[2*Nmax],rmq[20][4*Nmax];
vector <int> G[Nmax];

void dfs(int nod,int niv)
{
    H[++k] = nod;
    L[k] = niv;
    ap[nod] = k;
    for(auto it : G[nod])
    {
        dfs(it,niv+1);
        H[++k] = nod;
        L[k] = niv;
    }
}

void RMQ()
{
    for(int i=2;i<=k;i++)
        lg[i] = lg[i/2] +1;
    for(int i=1;i<=k;i++)
        rmq[0][i] = i;
    for(int i=1; (1<<i) <= k; i++)
        for(int j=1; j <= k - (1<<i);j++)
            {
                int l=1 << (i-1);
                rmq[i][j] = rmq[i-1][j];
                if(L[rmq[i-1][j + l]] < L[rmq[i][j]])
                    rmq[i][j] = rmq[i-1][j + l];
            }
}

int lca(int x,int y)
{
    int dif,sol,l,ll;
    x=ap[x];
    y=ap[y];
    if(x>y)
        swap(x,y);
    dif=y-x+1;
    l=lg[dif];
    ll=dif-(1<<l);
    sol = rmq[l][x];
    if(L[sol] > L[rmq[l][x + ll]])
        sol = rmq[l][x + ll];
    return H[sol];
}

int main()
{
    fscanf(in,"%d%d",&n,&m);
    for(int i=2;i<=n;i++)
    {
      int a;
      fscanf(in,"%d",&a);
      G[a].push_back(i);
    }
    dfs(1,0);
    RMQ();
    while(m--)
    {
        int a,b;
        fscanf(in,"%d%d",&a,&b);
        fprintf(out,"%d\n",lca(a,b));
    }
    return 0;
}