Cod sursa(job #862156)

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

using namespace std;

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

vector<int> a[NMAX];
queue<int> q;

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

void Citeste()
{
    int i;

    f>>n>>T;

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

void BFS()
{
    int i, nod;

    q.push(1); ad[1]=0;

    while (!q.empty())
    {
        nod=q.front(); q.pop();

        for (i=0; i<a[nod].size(); ++i)
        {
            q.push(a[nod][i]);
            ad[a[nod][i]]=ad[nod]+1;
        }
    }
}

void Parcurge_Euler(int nod)
{
    int i;

    mn[0][++lg]=nod;
    if (!pz[nod]) pz[nod]=lg;

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

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

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

        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];
    }
}

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

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

        px=min(pz[x], pz[y]);
        py=max(pz[x], pz[y]);

        lung=py-px+1; m=1; nr=0;

        while (m<<1<=lung)
        {
            m=m<<1;
            ++nr;
        }

        sol=mn[nr][py];

        lung=lung-m; py-=m;

        while (lung>0)
        {
            m=1; nr=0;

            while (m<<1<=lung)
            {
                m=m<<1;
                ++nr;
            }

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

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

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

int main()
{
    Citeste();
    BFS();
    Parcurge_Euler(1);
    /*int i;
    for (i=1;i<=lg; ++i) g<<mn[0][i]<<" "; g<<"\n";*/
    RMQ();
    Query();
    f.close();
    g.close();
    return 0;
}