Cod sursa(job #902662)

Utilizator deea101Andreea deea101 Data 1 martie 2013 15:56:02
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.4 kb
#include <fstream>
#include <iostream>
#include <vector>
#define nmax 100001
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
vector <int> v[nmax];
int n,r[18][2*nmax],e[2*nmax],k=1,viz[nmax],lg[2*nmax],p[nmax],l[nmax];
void euler(int nod, int lev)
{
    int i;
    viz[nod]=1;
    l[nod]=lev;
    p[nod]=k;
    e[k++]=nod;
    for(i=0;i<v[nod].size();i++)
    {
        if(!viz[v[nod][i]])
        {
            euler(v[nod][i],lev+1);
            e[k++]=nod;
        }
    }
}

void rmq()
{
    int i,j;
    lg[1]=0;
    for(i=2;i<k;i++)
        lg[i]=lg[i/2]+1;

    for(i=1;i<k;i++)
        r[0][i]=i;

    for(i=1;(1<<i)<k;i++)
    {
        for(j=1;j<k;j++)
        {
            r[i][j]=r[i-1][j];
            if(j+(1<<(i-1))<k && l[e[r[i-1][j+(1<<(i-1))]]]<l[e[r[i][j]]])
                r[i][j]=r[i-1][j+(1<<(i-1))];
        }
    }
}
int lca(int x, int y)
{
    int a,b,aux,dif,o,sol;
    a=p[x]; b=p[y];
    if(a>b) {aux=a; a=b; b=aux;}
    dif=b-a+1;
    sol=e[r[lg[dif]][a]];
    o=dif-(1<<lg[dif]);
    if( o && l[e[r[lg[dif]][a+o]]]<l[sol])
        sol=e[r[lg[dif]][a+o]];
    return sol;
}
int main()
{
    f>>n;
    int i,j,x,y,m;
    f>>m;
    for(i=2;i<=n;i++)
    {
        f>>x;
        v[x].push_back(i);
    }
    euler(1,1);
    rmq();
    for(i=0;i<m;i++)
    {
        f>>x>>y;
        g<<lca(x,y)<<'\n';
    }
}