Cod sursa(job #1204705)

Utilizator pentrusandaPentru Sanda pentrusanda Data 3 iulie 2014 18:25:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.75 kb
#include <fstream>
#include <iostream>

using namespace std;

struct nod
{
    int urm;
    nod *adr;
};

typedef nod *lda1;

lda1 lda[100005];

int n,m,x,y,peuler[200005],nr,trecut[100005],ad[200005],pra[100005],rmq[200005][21],put[25],apr[400005];

void adauga(lda1 &a,int b)
{
    lda1 p=new nod;
    p->urm=b;
    p->adr=a;
    a=p;
}

void parc(int nod,int h)
{
    trecut[nod]=1;
    ++nr; peuler[nr]=nod; ad[nr]=h; if (pra[nod]==0) pra[nod]=nr;
    for (lda1 p=lda[nod];p!=0;p=p->adr)
    {
        if (trecut[p->urm]==0)
        {
            parc(p->urm,h+1);
            ++nr; peuler[nr]=nod; ad[nr]=h;
        }
    }
}

int main()
{
    ifstream in ("lca.in");
    ofstream out ("lca.out");

    in>>n>>m;

    for (int i=2;i<=n;++i)
    {
        in>>x;
        adauga(lda[x],i);
        adauga(lda[i],x);
    }


    nr=0;
    parc(1,1);


    put[0]=1;
    for (int i=1;i<25;++i) put[i]=put[i-1]*2;
    apr[0]=0;
    for (int i=1;i<400005;++i) { apr[i]=apr[i-1]; if (put[apr[i]+1]==i) apr[i]++; }
    for (int i=nr;i>0;--i)
    {
        rmq[i][0]=i;
        for (int j=1;j<21;++j)
        {
            if (i+put[j]-1<=nr)
            {
                rmq[i][j]=rmq[i][j-1];
                if (ad[rmq[i+put[j-1]][j-1]]<ad[rmq[i][j]]) rmq[i][j]=rmq[i+put[j-1]][j-1];
            }
        }
    }

    for (int i=1;i<=m;++i)
    {
        in>>x>>y;
        int v1=pra[x],v2=pra[y];
        if (v2<v1) { int t=v1; v1=v2; v2=t; }
        int dif=v2-v1+1,minim;
        minim=rmq[v1][apr[dif]];
        if (ad[rmq[v2-put[apr[dif]]+1][apr[dif]]]<ad[minim]) minim=rmq[v2-put[apr[dif]]+1][apr[dif]];
        out<<peuler[minim]<<"\n";
    }

    in.close();
    out.close();
    return 0;
}