Cod sursa(job #1032951)

Utilizator dumitrualexAlex Dumitru dumitrualex Data 16 noiembrie 2013 11:27:06
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.19 kb
#include <fstream>
#include <vector>
#include <algorithm>
#define inf 1 << 30
#define FOR(i, a, b) for(int i = (a); i <= (b); i++)
#define nmax 100000+5
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

int poz_euler[nmax];
int * heap;
int adancime[nmax];
vector<int> u[nmax];
vector<int> euler;
int n, m;

void actualizare_arbint(int nod, int st, int dr)
{
    int mijl = (st+dr)/2;
    int x, y;
    if (st == dr)
        heap[nod] = euler[st];
    else
    {
        actualizare_arbint(2*nod, st, mijl);
        actualizare_arbint(2*nod+1, mijl+1, dr);
        if (adancime[heap[2*nod]] < adancime[heap[2*nod+1]])
            heap[nod] = heap[2*nod];
        else
            heap[nod] = heap[2*nod+1];
    }
}

int interogare_arbint(int nod, int st, int dr, int a, int b)
{
    int mijl = (st+dr)/2;
    int x, y;
    x = y = -1;
    if (a <= st && dr <= b)
        return heap[nod];
    else
    {
        if (a <= mijl)
            x = interogare_arbint(2*nod, st, mijl, a, b);
        if (b >= mijl+1)
            y = interogare_arbint(2*nod+1, mijl+1, dr, a, b);
        if (x == -1)
            return y;
        if (y == -1)
            return x;
        if (adancime[x] < adancime[y])
            return x;
        return y;
    }
}
void parcurgere_euler(int nod, int h)
{
    euler.push_back(nod);
    poz_euler[nod] = euler.size()-1;
    adancime[nod] = h;
    if (!u[nod].empty())
    {
        FOR(i, 0, u[nod].size()-1)
        {
            parcurgere_euler(u[nod][i], h+1);
            euler.push_back(nod);
        }
    }
}

void debug()
{
    FOR(i, 0, euler.size()-1)
        fout << euler[i] << ' ';
    fout << '\n';
}
int main()
{
    int x, y;
    fin >> n >> m;
    FOR(i, 2, n)
    {
        fin >> x;
        u[x].push_back(i);
    }
    parcurgere_euler(1, 1);
    int l = euler.size();
    heap = new int[l * 4];
    actualizare_arbint(1, 0, l-1);
    FOR(i, 1, m)
    {
        fin >> x >> y;
        int minim = min(poz_euler[x], poz_euler[y]);
        int maxim = max(poz_euler[x], poz_euler[y]);
        fout << interogare_arbint(1, 0, l-1, minim, maxim) << '\n';
    }
    return 0;
}