Cod sursa(job #1813818)

Utilizator DenisONIcBanu Denis Andrei DenisONIc Data 23 noiembrie 2016 12:54:01
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.48 kb
#include <fstream>
#include <vector>
#include <cmath>
#define Nmax 100001
using namespace std;

ofstream g("lca.out");

struct EU{
    int niv,nod;
}euler[Nmax*4],rmq[20][Nmax*4];

int nr,n,m,t[Nmax+1],fst[Nmax+1];
vector<int> G[Nmax+1];

void dfs(int nod,int niv)
{
    euler[++nr].niv = niv;
    euler[nr].nod = nod;
    fst[nod] = nr;
    for (int i=0;i<G[nod].size();i++)
    {
        int crt = G[nod][i];
        dfs(crt,niv+1);
        euler[++nr].niv = niv;
        euler[nr].nod = nod;
    }
}

int lca(int a,int b)
{
    if (a<b)
    {
        int aux = a;
        a = b;
        b = aux;
    }
    int dif = a - b + 1;
    int p = log2(dif);
    if (rmq[p][b].niv<rmq[p][a-(1<<p)+1].niv)
        return rmq[p][b].nod;
    return rmq[p][a-(1<<p)+1].nod;
}

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

    scanf("%ld%ld",&n,&m);
    for (int i=2;i<=n;i++)
    {
        scanf("%ld",&t[i]);
        G[t[i]].push_back(i);
    }
    dfs(1,1);

    for (int i=1;i<=nr;i++)
        rmq[0][i] = euler[i];

    for (int i=1;(1<<i)<=nr;i++)
    {
        for (int j=1;j<=nr-(1<<i)+1;j++)
        {
            if (rmq[i-1][j].niv<rmq[i-1][j+(1<<(i-1))-1].niv)
                rmq[i][j] = rmq[i-1][j];
            else
                rmq[i][j] = rmq[i-1][j+(1<<(i-1))-1];
        }
    }

    int x,y;
    for (int i=1;i<=m;i++)
    {
        scanf("%ld%ld",&x,&y);
        g<<lca(fst[x],fst[y])<<'\n';
    }


    return 0;
}