Cod sursa(job #1329628)

Utilizator okros_alexandruOkros Alexandru okros_alexandru Data 29 ianuarie 2015 18:40:21
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.15 kb
#include <fstream>
#include <vector>

#define Lmax 19
#define Nmax 100100

using namespace std;

vector <int> Tree[Nmax];
vector < pair<int, int> > Euler;
int N, First[Nmax];

class RangeMinimumQuery {

    private:
        int size, Log2[Nmax << 1], Rmq[Lmax][Nmax << 1];

    public:
        void init(int Size) {

            size = Size;

            for(int i = 2; i <= size; i++)
                Log2[i] = Log2[i >> 1] + 1;

            for(int i = 1; i <= size; i++)
                Rmq[0][i] = i;
        }

        void process() {

            int i, j;

            for(i = 1; (1 << i) <= size; i++)
                for(j = 1; j <= size - (1 << i) + 1; j++)
                    if(Euler[Rmq[i - 1][j]].second < Euler[Rmq[i - 1][j + (1 << (i-1))]].second)
                        Rmq[i][j] = Rmq[i - 1][j];
                    else
                        Rmq[i][j] = Rmq[i - 1][j + (1 << (i-1))];

        }

        void update(int index, int value) {
            Rmq[0][index] = value;
        }

        int query(int x, int y) {

            x = First[x];
            y = First[y];

            if(x > y)
                swap(x, y);

            int log2 = Log2[y - x + 1];
            if(Euler[Rmq[log2][x]].second < Euler[Rmq[log2][y - (1 << log2) + 1]].second)
                return Euler[Rmq[log2][x]].first;
            else
                return Euler[Rmq[log2][y - (1 << log2) + 1]].first;
         }
} rmq;


void Dfs(int node, int level) {

    First[node] = Euler.size();
    Euler.push_back(make_pair(node, level));

    for(int i = 0; i < Tree[node].size(); i++) {
        Dfs(Tree[node][i], level + 1);
        Euler.push_back(make_pair(node, level));
    }
}
int main() {

    int i, x, y, queries;
    ifstream in("lca.in");
    ofstream out("lca.out");

    in >> N >> queries;
    for(i = 2; i <= N; i++) {
        in >> x;
        Tree[x].push_back(i);
    }

    Dfs(1, 0);
    rmq.init(Euler.size());
    rmq.process();

    while(queries--) {
        in >> x >> y;
        out << rmq.query(x, y) << '\n';
    }

    in.close();
    out.close();

    return 0;
}