Cod sursa(job #1227161)

Utilizator pop_bogdanBogdan Pop pop_bogdan Data 9 septembrie 2014 16:14:20
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.96 kb
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;

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

int N, M, x, y, L, minim(99999999), st, dr, O;
int Vis[100001],B[100001];
vector <int> G[100001];
int H[2*100001],E[2*100001],Sz;
int VA[6*100001];

void Input();
void DFS(int node, int lv);
void Build(int node, int left, int right);
void Query(int node, int left, int right);
void Debug();

int main()
{
    int maxim(-1),minst(9999999),mindr(9999999);
    Input();
    DFS(1,0);
    Build(1,1,Sz);
    Debug();
    for ( int i = 1; i <= M; ++i )
    {
        minim = 9999999;
        is >> x >> y;
        st = B[x];
        dr = B[y];
        if ( dr < st )
            swap(st,dr);
        Query(1,1,Sz);
        os << O << '\n';
    }

    is.close();
    os.close();
}

void Input()
{
    is >> N >> M;
    for ( int i = 2; i <= N; ++i )
    {
        is >> x;
        G[x].push_back(i);
    }
}

void DFS(int node, int lv)
{
    Sz++;
    E[Sz] = node;
    H[Sz] = lv;
    B[node] = Sz;

    for ( int i = 0; i < G[node].size(); ++i )
    {
            DFS(G[node][i],lv+1);
            Sz++;
            E[Sz] = node;
            H[Sz] = lv;
    }
}

void Debug()
{

}

void Build(int node, int left, int right)
{
    if ( left == right )
    {
        VA[node] = left;
        return;
    }
    int mid = (left+right)/2;

    Build(2*node,left,mid);
    Build(2*node+1,mid+1,right);

    if ( H[VA[2*node]] <= H[VA[2*node+1]] )
        VA[node] = VA[2*node];
    else
        VA[node] = VA[2*node+1];
}

void Query(int node, int left, int right)
{
    if ( st <= left && right <= dr )
    {
        if ( minim > H[VA[node]] )
        {
            minim = H[VA[node]];
            O = E[VA[node]];
        }
        return;
    }
    int mij = (left+right)/2;

    if ( st <= mij ) Query(node*2,left,mij);
    if ( mij < dr ) Query(node*2+1,mij+1,right);
}