Cod sursa(job #1378668)

Utilizator andreimdvMoldovan Andrei andreimdv Data 6 martie 2015 13:36:21
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.89 kb
#include <fstream>
#include<vector>
using namespace std;

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

int pos,val,minim,n,i,t,a,b,start,finish,x,m;
vector<int> v[100010];
int vizitat[100010],level[100010],euler[200010],aint[400010];

void update(int nod,int left,int right)
{
    if(left==right)
    {
        aint[nod]=val;
        return;
    }
   int  mij=(left+right)/2;
    if(pos<=mij) update(2*nod,left,mij);
    else update(2*nod+1,mij+1,right);

    if(level[aint[2*nod]]<= level[aint[2*nod+1]])
        aint[nod]=aint[2*nod];
    else
        aint[nod]=aint[2*nod+1];
}

void querry(int nod,int left,int right)
{
    if(left>=start&&right<=finish)
    {
        if(level[aint[nod]]<level[minim])
            minim=aint[nod];
        return;
    }
    int mij=(left+right)/2;
    if(start<=mij) querry(2*nod,left,mij);
    if(finish>mij) querry(2*nod+1,mij+1,right);

}

void dfs(int x,int niv)
{

    int i;
    //fout<<x<<" ";
    euler[++t]=x;
    if(vizitat[x]==-1)
        vizitat[x]=t;
    level[x]=niv;
    for(i=0;i<v[x].size();++i)
    {
        dfs(v[x][i],niv+1);
        euler[++t]=x;
        //fout<<x<<" ";
    }
}


int main()
{
    fin>>n>>m;
    for(i=2;i<=n;++i)
    {
        fin>>x;
        v[x].push_back(i);
    }

    for(i=1;i<=n;++i) vizitat[i]=-1;
    dfs(1,0); //reprezentarea euler

    //for(i=1;i<=t;++i)
      //  fout<<euler[i]<<" "<<level[euler[i]]<<'\n';

    level[0]=1<<30;
    //! formare arbore de intervale
    for(i=1;i<=t;++i)
    {
        val=euler[i];
        pos=i;
        update(1,1,t);
    }

    //!querry
        for(i=1;i<=m;++i)
        {
            fin>>a>>b;
            start=min(vizitat[a],vizitat[b]);
            finish=max(vizitat[a],vizitat[b]);
            minim=1<<30;
            querry(1,1,t);
            fout<<minim<<'\n';
        }



    return 0;
}