Cod sursa(job #885767)

Utilizator deea101Andreea deea101 Data 22 februarie 2013 12:26:40
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <fstream>
#include <iostream>
#include <vector>
#define nmax 100001
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
vector <int> vec[nmax];
int n,k=1,level[2*nmax],e[2*nmax],first[nmax],lg[2*nmax];
int rmq[20][nmax];
void euler(int nod,int lev)
{
    e[k]=nod;
    level[k]=lev;
    if(!first[nod]) first[nod]=k;
    k++;

    int i;
    for(i=0;i<vec[nod].size();i++)
    {
        euler(vec[nod][i],lev+1);
        e[k]=nod;
        level[k]=lev;
        k++;
    }

}

void rangemin()
{
    int i,j;
    for(i=1;i<=k;i++) rmq[0][i]=i;
    for(i=1;(1<<i)<=k;i++)
    {
        for(j=1;j<=k;j++)
        {
            if(j+(1<<(i-1))<=k && level[rmq[i-1][j]]>level[rmq[i-1][j+(1<<(i-1))]])
                rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
            else rmq[i][j]=rmq[i-1][j];
        }
    }
}
int lca(int x, int y)
{

    int a,b,dif,sol;
    a=first[x]; b=first[y];
    if(a>b) swap(a,b);
    dif=b-a+1;
    sol=rmq[lg[dif]][a];
    if(dif-(1<<lg[dif]) && level[rmq[lg[dif]][a+dif-(1<<lg[dif])]]<level[sol])
        sol=rmq[lg[dif]][a+dif-(1<<lg[dif])];

    return e[sol];
}
int main()
{
    int i,j,m,x,y;
    f>>n>>m;
    for(i=2;i<=n;i++)
    {
        f>>x;
        vec[x].push_back(i);
    }

    euler(1,1); k-=1;
    rangemin();

    lg[1]=0;
    for(i=2;i<=k;i++) lg[i]=lg[i/2]+1;

    for(i=0;i<m;i++)
    {
        f>>x>>y;
        g<<lca(x,y)<<'\n';
    }

}