Cod sursa(job #1969260)

Utilizator TibixbAndrei Tiberiu Tibixb Data 18 aprilie 2017 12:57:03
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.24 kb
#include<fstream>
#include<vector>
#define NMAX 100000
#define INF 2000000000
using namespace std;
vector<int> G[NMAX + 5];
int n, m, x, y, _length, p;
int lca_first[NMAX + 5];
int nn;
int _p[2 * NMAX + 5];
bool u[NMAX + 5];
struct _struct
{
    int niv;
    int nod;
};
_struct sol;
_struct d[18][2 * NMAX];
ifstream _cin("lca.in");
ofstream _cout("lca.out");

_struct min_defined(_struct x, _struct y)
{
    if(x.niv == y.niv)
    {
        if(x.nod < y.nod)
        {
            return x;
        }else
        {
            return y;
        }
    }else
    {
        if(x.niv < y.niv)
        {
            return x;
        }else
        {
            return y;
        }
    }
}

void d_euler(int nod, int niv)
{
    u[nod] = 1;

    d[0][++nn].nod = nod;
    d[0][nn].niv = niv;
    lca_first[nod] = nn;

    for(int i = 0; i < G[nod].size(); i++)
    {
        int fiu = G[nod][i];
        if(u[fiu] == 0)
        {
            d_euler(fiu, niv + 1);
            d[0][++nn].nod = nod;
            d[0][nn].niv = niv;
        }
    }
}

void power_calculation()
{
    for(int i = 1 + 1; i <= 2 * NMAX; i++)
    {
        _p[i] = 1 + _p[i / 2];
    }
}

void rmq()
{
    for(int i = 1; (1 << i) <= nn; i++)
    {
        for(int j = 1; j <= nn; j++)
        {
            d[i][j] = d[i - 1][j];
            if(j + (1 << (i - 1)) <= nn)
            {
                d[i][j] = min_defined(d[i - 1][j],
                            d[i - 1][j + (1 << (i - 1))]);
            }
        }
    }
}

int main()
{
    _cin >> n >> m;
    for(int i = 1 + 1; i <= n; i++)
    {
        _cin >> x;
        G[x].push_back(i);
        G[i].push_back(x);
    }

    d_euler(1, 1);

    rmq();

    power_calculation();

    for(int i = 1; i <= m; i++)
    {
        sol.niv = INF;

        _cin >> x >> y;

        x = lca_first[x];
        y = lca_first[y];

        if(x > y)
        {
            swap(x, y);
        }

        _length = (y - x + 1);
        p = _p[_length];

        sol = min_defined(d[p][x],
            d[p][y - (1 << p) + 1]);
        _cout << sol.nod << "\n";
    }

    return 0;
}