Cod sursa(job #1494591)

Utilizator AdrianaMAdriana Moisil AdrianaM Data 1 octombrie 2015 15:05:44
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.79 kb
#include <fstream>
#include <vector>
#include <bitset>
#define INF 0x3f3f3f3f
using namespace std;

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

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

int n, m;
VI e, poz, niv, log;
VVI g, r;

void Read();
void Euler(int nod, int k);
void RMQ();

int main()
{
    Read();
    e.push_back(0);
    niv.push_back(0);
    poz = VI(n + 1);
    Euler(1, 1);
    RMQ();
    int x, y, val;
    while ( m-- )
    {
        is >> x >> y;
        x = poz[x];
        y = poz[y];
        val = log[y - x + 1];
        if ( x > y )
            swap(x, y);
        if ( niv[r[x][val]] < niv[r[y - ( 1 << val ) + 1 ][val]] )
            os << e[r[x][val]] << "\n";
        else
            os << e[r[y - ( 1 << val ) + 1 ][val]] << "\n";
    }
    is.close();
    os.close();
    return 0;
}

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

void Euler(int nod, int k)
{
    poz[nod] = e.size();
    for ( const auto &nodv : g[nod] )
        if ( !poz[nodv] )
        {
            e.push_back(nod);
            niv.push_back(k);
            Euler(nodv, k + 1);
        }
    e.push_back(nod);
    niv.push_back(k);
}

void Read()
{
    int x;
    is >> n >> m;
    g = VVI(n + 1);
    for ( int i = 2; i <= n; ++i )
    {
        is >> x;
        g[x].push_back(i);
    }
}