Cod sursa(job #1492789)

Utilizator horiainfoTurcuman Horia horiainfo Data 28 septembrie 2015 10:44:22
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.27 kb
#include <fstream>
#include <cmath>
#include <vector>

#define NMAX 100005
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

int nr, v[NMAX*2],level[NMAX*2];
int mat[NMAX][20];
struct graf{int poz; vector<int> next;} nod[NMAX];

void euler(int nod,int level)
{
    v[++nr] = nod;
    ::level[nr] = level; ::nod[nod].poz = nr;
    for(int i=0;i<(::nod[nod].next.size());i++)
    {
        euler(::nod[nod].next[i],level+1);
        v[++nr] = nod;
        ::level[nr] = level;
    }
}

void rmq()
{
    int k;
    for(int i=1;i<=nr;i++)
        mat[i][0]=i;

   for(int j=1;(k=1<<j)<=nr;j++)
       for(int i=1;i+k-1<=nr;i++)
           mat[i][j] = level[mat[i][j-1]] <= level[mat[i+k/2][j-1]] ? mat[i][j-1] : mat[i+k/2][j-1];
}

int query(int inc,int sf)
{
    int j = log2(sf-inc+1);
    return level[mat[inc][j]] <= level[mat[sf-(1<<j)+1][j]] ? v[mat[inc][j]] : v[mat[sf-(1<<j)+1][j]];
}

int main()
{
    int a,n,m,root,b;
    fin>>n>>m;
    for(int i=2;i<=n;i++)
    {

        fin>>a;
        nod[a].next.push_back(i);
    }

    euler(1,1);
    rmq();

    for(int i=1;i<=m;i++)
    {
        fin>>a>>b;
        fout<<query(min(nod[a].poz,nod[b].poz),max(nod[a].poz,nod[b].poz))<<'\n';
    }
    return 0;
}