Cod sursa(job #936713)

Utilizator dutzulBodnariuc Dan Alexandru dutzul Data 8 aprilie 2013 15:04:46
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.75 kb
#include <fstream>
using namespace std;
#define LE 100666
#include <vector>
ifstream f ( "lca.in" );
ofstream g ( "lca.out" );
vector<int> H[LE];
int suv[3*LE], tree[15*LE];
bool viz[LE];
int level[LE], aparr[LE], k, x, y;
int m, n, result, i, father;
#define inf 1<<30
#define pb push_back

void dfs ( int nod, int lev )
{
    level[nod] = lev;
    aparr[nod] = ++k;
    suv[k] = nod;
    int N = H[nod].size();
    viz[nod] = true;

    for ( int i = 0; i < N; ++i ) if (viz[H[nod][i]]==false)
    {
        dfs ( H[nod][i], lev + 1 );
        suv[++k] = nod;
    }
}
void build_tree ( int st, int dr, int nod )
{
    if ( st == dr )  tree[nod] = suv[dr];
    if ( st >= dr ) return;

    int mij =  ( st + dr ) / 2;
    build_tree ( st, mij, nod * 2 );
    build_tree ( mij + 1, dr, nod * 2 + 1 );

    if ( level[tree[nod*2]] < level[tree[nod*2+1]] )
        tree[nod] = tree[nod*2];
    else
        tree[nod] = tree[nod*2+1];
}
void query ( int st, int dr, int nod )
{
    if ( st >= x && dr <= y )
    {
        if ( level[tree[nod]] < level[result] )
            result = tree[nod];

        return;
    }
    int mij = ( st + dr ) / 2;
    if ( mij >= x ) query ( st, mij, nod * 2 );
    if ( mij + 1 <= y ) query ( mij + 1, dr, nod * 2 + 1 );
}
int main()
{
    f >> n >> m;

    for ( i = 2; i <= n; ++i )
    {
        f >> father;
        H[i].pb ( father );
        H[father].pb ( i );
    }
    dfs ( 1, 1 );
    build_tree(1,k,1);

    level[0]=inf;

    for ( i = 1; i <= m; ++i )
    {
        f >> x >> y; x=aparr[x];y=aparr[y];
        if (x>y) swap(x,y);
        result = 0;
        query ( 1, k, 1 );
        g << result << '\n';
    }

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