Cod sursa(job #902912)

Utilizator costi_.-.Costinnel costi_.-. Data 1 martie 2013 17:26:15
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.68 kb
#include<fstream>
#define nmax 300003
#define inf 1<<30
using namespace std;

struct nod_lista{
    int val;
    nod_lista *link;
};

nod_lista *G[nmax],*Last[nmax];
int eu[nmax],nivel[nmax],nivelsep[nmax],A[4*nmax],indice[nmax],viz[nmax];
int Px[nmax],Py[nmax],Rez[nmax],kr,ek,N,M;


inline int schimba(int& a,int& b)
{
    int c=a;
    a=b;
    b=c;
}
inline int minim(int a,int b)
{
    if(a<b)
    return a;
    return b;
}
//Proceduri arbori
void update(int nod,int st,int dr,int& poz,int& val)
{
    int mij;
    if(st==dr)
    A[nod]=val;
    else
    {
        mij=(st+dr)/2;
        if(poz<=mij)
        update(nod<<1,st,mij,poz,val);
        else
        update((nod<<1)+1,mij+1,dr,poz,val);

        if(nivel[indice[A[nod<<1]]]<nivel[indice[A[(nod<<1)+1]]])
           A[nod]=A[nod<<1];
           else
           A[nod]=A[2*nod+1];
    }
}

void query(int nod,int st,int dr,int& a,int& b,int& rez)
{
    if(a<=st && dr<=b)
     {if(nivel[indice[A[nod]]]<nivel[indice[rez]])
     rez=A[nod];}

    else
    {
        int mij=(st+dr)/2;
        if(a<=mij)
        query(nod<<1,st,mij,a,b,rez);
        if(b>mij)
        query((nod<<1)+1,mij+1,dr,a,b,rez);
    }
}

void adauga(int unde,int ce)
{
    nod_lista *q=new nod_lista;

    q->val=ce;
    q->link=NULL;
    if(!G[unde])
    G[unde]=Last[unde]=q;
    else
    {
        Last[unde]->link=q;
        Last[unde]=q;
    }
}


void citeste()
{
    ifstream f("lca.in");
    int i,x;

    f>>N>>M;
    for(i=1;i<=N-1;i++)
    {
        f>>x;
        adauga(i+1,x);
        adauga(x,i+1);
    }
    for(i=1;i<=M;i++)
    {
        f>>Px[i]>>Py[i];
        if(Px[i]>Py[i])
        schimba(Px[i],Py[i]);
    }

    f.close();
}




void Euler(int nod)
{
    eu[++ek]=nod;
    indice[nod]=ek;
    nivel[ek]=nivelsep[nod];

    nod_lista *q=G[nod];
    while(q)
    {
        if(!viz[q->val])
        {
            viz[q->val]=1;
            nivelsep[q->val]=nivelsep[nod]+1;

            Euler(q->val);


            eu[++ek]=nod;
            nivel[ek]=nivelsep[nod];
        }
        q=q->link;
    }
}

void construieste()
{
    int i;
    for(i=1;i<=ek;i++)
    update(1,1,ek,i,eu[i]);
}

void rezolva()
{
    nivel[nmax]=inf;
    indice[nmax]=nmax;
    viz[1]=1;
    Euler(1);

    construieste();

    for(int i=1;i<=M;i++)
    {
        Rez[i]=nmax;
        query(1,1,ek,indice[Px[i]],indice[Py[i]],Rez[i]);
    }
}

void scrie()
{
    ofstream g("lca.out");
    int i;


    for(i=1;i<=M;i++)
    g<<Rez[i]<<'\n';


    g.close();
}

int main()
{
    citeste();
    rezolva();
    scrie();
    return 0;
}