Cod sursa(job #1251161)

Utilizator okros_alexandruOkros Alexandru okros_alexandru Data 28 octombrie 2014 23:42:14
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.1 kb
#include <fstream>
#include <vector>

#define Nmax 100100
#define Mmax Nmax << 1
#define Lmax 18
#define log2 Log2[B - A + 1]
#define pb push_back
#define mkp make_pair
#define Neighbour Graph[Node][i]
#define guessWho(x) Euler[x].first
#define Level(x) Euler[x].second

using namespace std;

vector < pair<int, int> > Euler;
vector <int> Graph[Nmax];
int N, M, T, First[Nmax];

class Rmq {

    private:
        int Rmq[Lmax][Mmax], Log2[Mmax];

    public:

        void process() {

            int i, j;

            M = (N << 1);

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

            for(i = 1; i <= M; i++)
                Rmq[0][i] = i;

            for(i = 1; (1 << i) <= M; i++)
                for(j = 1; j <= M - (1 << i) + 1; j++)
                    if(Level(Rmq[i - 1][j]) < Level(Rmq[i-1][j + (1 << (i - 1))]))
                        Rmq[i][j] = Rmq[i - 1][j];
                    else
                        Rmq[i][j] = Rmq[i-1][j + (1 << (i - 1))];

        }

        int lca(int A, int B) {

            A = First[A];
            B = First[B];

            if(A > B)
                swap(A, B);

            if(Level(Rmq[log2][A]) < Level(Rmq[log2][B - (1 << log2) + 1]))
                return guessWho(Rmq[log2][A]);
            else
                return guessWho(Rmq[log2][B - (1 << log2) + 1]);

        }

} rmq;

void Dfs(int Node, int Level) {

    First[Node] = Euler.size();
    Euler.pb(mkp(Node, Level));

    for(int i = 0; i < Graph[Node].size(); i++) {
        Dfs(Neighbour, Level + 1);
        Euler.pb(mkp(Node, Level));
        }

}
void Read(ifstream & in) {

    int i, x;

    in >> N >> T;

    for(i = 2; i <= N; i++) {
        in >> x;
        Graph[x].pb(i);
        }

}
int main() {

    int i, x, y;

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

    Read(in);
    Dfs(1, 0);

    rmq.process();

    while(T--) {

        in >> x >> y;
        out << rmq.lca(x, y) << '\n';

        }

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

    return 0;

}