Cod sursa(job #862178)

Utilizator marta_diannaFII Filimon Marta Diana marta_dianna Data 22 ianuarie 2013 12:56:51
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.82 kb
#include<fstream>
#include<vector>
#define NMAX 100010
#define LGP 200020
#define KMAX 20

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

vector<int> a[NMAX];

int n, T, lg, tata[NMAX], ad[NMAX],  mn[KMAX][LGP], pz[NMAX], b[LGP], apr[LGP];

void Citeste()
{
    int i;

    f>>n>>T;

    for (i=2; i<=n; ++i)
    {
        f>>tata[i];
        a[tata[i]].push_back(i);
    }
}

void Parcurge_Euler(int nod, int nr)
{
    int i;

    ad[nod]=nr;
    mn[0][++lg]=nod;

    if (!pz[nod]) pz[nod]=lg;

    for (i=0; i<a[nod].size(); ++i)
    {
        Parcurge_Euler(a[nod][i], nr+1);
        mn[0][++lg]=nod;
        if (!pz[nod]) pz[nod]=lg;
    }
}

void RMQ()
{
    int k=0, i, z, zp=1;

    for (k=1; 1<<k<=lg; ++k)
    {
        z=1<<k;

        for (i=z; i<=lg; i++)
            if (ad[mn[k-1][i]]<ad[mn[k-1][i-zp]]) mn[k][i]=mn[k-1][i];
            else mn[k][i]=mn[k-1][i-zp];

        zp=z;
    }
}

void Preprop()
{
    int i, p=1;

    apr[1]=1; b[1]=0; apr[2]=2; b[2]=1;

    for (i=3; i<=lg; ++i)
        if (apr[i-1]<<1==i) apr[i]=apr[i-1]<<1, b[i]=b[i-1]+1;
        else apr[i]=apr[i-1], b[i]=b[i-1];

}

void Query()
{
    int x, y, px, py, lung, m, nr=0, sol;

    while (T--)
    {
        f>>x>>y;

        px=pz[x];
        py=pz[y];

        if (px>py) swap(px, py);

        lung=py-px+1; m=apr[lung]; nr=b[lung];

        sol=mn[nr][py];

        lung=lung-m; py-=m;

        while (lung>0)
        {
            m=apr[lung]; nr=b[lung];

            if (ad[sol]>ad[mn[nr][py]]) sol=mn[nr][py];

            lung=lung-m; py-=m;
        }

        g<<sol<<"\n";
    }
}

int main()
{
    Citeste();
    Parcurge_Euler(1, 0);
    Preprop();
    RMQ();
    Query();

    f.close();
    g.close();
    return 0;
}