Cod sursa(job #1989601)

Utilizator Mihai_PredaPreda Mihai Dragos Mihai_Preda Data 8 iunie 2017 09:18:54
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.21 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

const int nMax = 100005;
const int logMax = 20;

class arbore
{
public:
    arbore(int * father, int n)
    {
        this->n = n;
        for(int i = 0; (1 << (i-1)) <= n; ++i)
            this->father[i] = new int[n+1];
        for(int i = 1; i <= n; ++i)
        {
            if(father[i] >= 1)
                child[father[i]].push_back(i);
            this->father[0][i] = father[i];
        }
        UpdateFathers();
        UpdateNivel();
    }
    ~arbore()
    {
        delete[] child;
        for(int i = 0; (1 << (i-1)) <= n; ++i)
            delete[] father[i];
    }
    int Query(int x, int y)
    {
        if(nivel[x] < nivel[y])
            swap(x, y);
        int step;
        for(step = 0; (1 << step) < n; ++step);
        for(int i = step; i >= 0; --i)
        {
            if(father[i][x] >= 1 && nivel[father[i][x]] >= nivel[y])
                x = father[i][x];
        }
        if(x == y)
            return x;
        for(int i = step; i >= 0; --i)
            if(father[i][x] != father[i][y])
                x = father[i][x], y = father[i][y];
        return father[0][x];
    }
private:
    void UpdateFathers()
    {
        for(int i = 1; (1 << (i-1)) <= n; ++i)
            for(int j = 1; j <= n; ++j)
            {
                if(father[i-1][j] < 1)
                    father[i][j] = father[i-1][j];
                else
                    father[i][j] = father[i-1][father[i-1][j]];
            }
    }
    void UpdateNivel(int current = 1, int niv = 1)
    {
        nivel[current] = niv;
        for(auto c:child[current])
            UpdateNivel(c, niv + 1);
    }
    int n;
    int nivel[logMax];
    int * father[logMax]; //al 2^i-ulea father al lui j
    vector<int> child[nMax];
};

int n, m;
int father[nMax];

int main()
{
    ifstream in("lca.in");
    ofstream out("lca.out");
    in >> n >> m;
    father[1] = -1;
    for(int i = 2; i <= n; ++i)
        in >> father[i];
    arbore arb(father, n);
    int x, y;
    for(int i = 1; i <= m; ++i)
    {
        in >> x >> y;
        out << arb.Query(x, y) << "\n";
    }
    return 0;
}