Cod sursa(job #1369401)

Utilizator AdrianaMAdriana Moisil AdrianaM Data 3 martie 2015 00:40:16
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include <fstream>
#include <vector>
using namespace std;

ifstream is("lca.in");
ofstream os("lca.out");

using VI = vector<int>;
using VVI = vector<VI>;

int n, m, cnt;
VI e, nv, poz, log2;
VVI g, answ;

void Read();
void DF(int nod, int niv);
void RMQ();

int main()
{
    Read();
    DF(1, 1);
    RMQ();
    int x, y, v;
    while ( m-- )
    {
        is >> x >> y;
        x = poz[x];
        y = poz[y];
        if ( y < x )
            swap(x, y);
        v = log2[y - x + 1];
        if ( nv[answ[x][v]] < nv[answ[y - (1 << v) + 1][v]] )
            os << e[answ[x][v]] << "\n";
        else
            os << e[answ[y - (1 << v) + 1][v]] << "\n";
    }
    is.close();
    os.close();
    return 0;
}

void RMQ()
{
    log2 = VI(2 * n);
    for ( int i = 2; i < 2 * n; ++i )
        log2[i] = log2[i / 2] + 1;
    answ = VVI(2 * n, VI(20));
    for ( int i = 1; i < 2 * n; ++i )
        answ[i][0] = i;
    for ( int j = 1; (1 << j) < 2 * n; ++j )
        for ( int i = 1; i + (1 << j) - 1 < 2 * n; ++i )
            if ( nv[answ[i][j - 1]] < nv[answ[i + ( 1 << (j - 1))][j - 1]] )
                answ[i][j] = answ[i][j - 1];
            else
                answ[i][j] = answ[i + ( 1 << (j - 1))][j - 1];

}

void DF(int nod, int niv)
{
    e[++cnt] = nod;
    nv[cnt] = niv;
    poz[nod] = cnt;
    for ( const auto& nodv : g[nod] )
    {
        DF(nodv, niv + 1);
        e[++cnt] = nod;
        nv[cnt] = niv;
    }
}

void Read()
{
    is >> n >> m;
    g = VVI(n + 1);
    poz = VI(n + 1);
    e = nv = VI(2 * n);
    int nod;
    for ( int i = 2; i <= n; ++i )
    {
        is >> nod;
        g[nod].push_back(i);
    }
}