Cod sursa(job #1147851)

Utilizator marta_diannaFII Filimon Marta Diana marta_dianna Data 20 martie 2014 10:49:35
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.8 kb
#include<fstream>
#include<vector>
#define EMAX 200010
#define NMAX 100010
#define RMQMAX 17

using namespace std;

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

vector<int> a[NMAX];
int n, m, vz[NMAX], euler[EMAX], first[NMAX], level[EMAX], nxt[EMAX], rmq_lca[RMQMAX][EMAX];

void Citeste()
{
    int i, x;

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

void Euler(int x, int niv)
{
    int nod;
    vector<int> :: iterator it;

    euler[++euler[0]]=x;
    first[x]=euler[0];
    level[x]=niv;
    vz[x]=1;

    for (it=a[x].begin(); it!=a[x].end(); ++it)
    {
        nod=*it;
        if (!vz[nod])
        {
            Euler(nod, niv+1);
            euler[++euler[0]]=x;
        }
    }
}

void RMQ()
{
    int i, j, x, p=1, nr=0;

    level[n+1]=euler[0];
    for (i=1; i<=euler[0]; ++i)
    {
        rmq_lca[0][i]=euler[i];
        if (i==p*2){ p*=2; ++nr;}
        nxt[i]=nr;
    }

    for (i=1; (1<<i)<=euler[0]; ++i)
        for (j=1<<i; j<=euler[0]; ++j)
        {
            x=j-(1<<(i-1));
            if (level[rmq_lca[i-1][x]]<level[rmq_lca[i-1][j]]) rmq_lca[i][j]=rmq_lca[i-1][x];
            else rmq_lca[i][j]=rmq_lca[i-1][j];
        }
}

int lca(int x, int y)
{
    int pz, mn=n+1;

    x=first[x]; y=first[y];
    if (x>y) swap(x, y);
    while (x<=y)
    {
        pz=1<<nxt[y-x+1];
        if (level[mn]>level[rmq_lca[nxt[y-x+1]][y]]) mn=rmq_lca[nxt[y-x+1]][y];
        y=y-pz;
    }
    return mn;
}

void Solve()
{
    int x, y;

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

        g<<lca(x, y)<<"\n";
    }
}

int main()
{
    Citeste();

    Euler(1, 1);

    RMQ();

    Solve();

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