Cod sursa(job #1537879)

Utilizator hasmasandragosHasmasan Dragos hasmasandragos Data 28 noiembrie 2015 11:32:09
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include <bits/stdc++.h>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int nmax=200005;
int m,j,i,n,x,y,cont;
vector <int> a[nmax];
int euler[nmax],first[nmax],level[nmax],loga[nmax];
int rmq[20][nmax],nodmin[20][nmax];

void dfs (int nod)
{
    euler[++cont]=nod;
    first[nod]=cont;
    int fii,h;
    fii=a[nod].size();
    for (h=0;h<fii;h++)
    {
        level[a[nod][h]]=level[nod]+1;
        dfs(a[nod][h]);
        euler[++cont]=nod;
    }
}

int lca (int X, int Y)
{
    int aux,lun,p;
    X=first[X];
    Y=first[Y];
    if (X>Y) swap(X,Y);
    lun=Y-X+1;
    p=loga[lun];
    if (rmq[p][x]<rmq[p][y-(1<<p)+1])
     return nodmin[p][x];
    else
     return nodmin[p][y-(1<<p)+1];
}

int main()
{
    f>>n>>m;
    for (y=2;y<=n;y++)
    {
        f>>x;
        a[x].push_back(y);
    }

    dfs(1);

    for (i=2;i<=cont;i++)
     loga[i]=loga[i/2]+1;

    for (i=1;i<=cont;i++)
    {
        rmq[0][i]=level[euler[i]];
        nodmin[0][i]=euler[i];
    }

    for (i=1;(1<<i)<=cont;i++)
     for (j=1;j+(1<<i)-1<=cont;j++)
     {
         if (rmq[i-1][j]<rmq[i-1][j+(1<<(i-1))])
         {
             rmq[i][j]=rmq[i-1][j];
             nodmin[i][j]=nodmin[i-1][j];
         }
         else
         {
             rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
             nodmin[i][j]=nodmin[i-1][j+(1<<(i-1))];
         }
     }

     while (m--)
     {
         f>>x>>y;
         g<<lca(x,y)<<'\n';
     }

    return 0;
}