Cod sursa(job #1248752)

Utilizator crucerucalinCalin-Cristian Cruceru crucerucalin Data 25 octombrie 2014 22:00:46
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.98 kb
#include <fstream>
#include <vector>
#include <list>
#include <algorithm>
#include <cmath>
#include <iostream>

using namespace std;



void getEulers(int node, int level, vector< list<int> > &adj,
               vector< pair<int, int> > &output,
               vector<int> &first_idx)
{
    first_idx[node] = output.size();
    for (list<int>::const_iterator it = adj[node].cbegin();
         it != adj[node].cend(); ++it) {
        output.emplace_back(level, node);
        getEulers(*it, level + 1, adj, output, first_idx);
    }
    output.emplace_back(level, node);
}


vector< vector< pair<int, int> > > getRmq(vector< pair<int, int> > &out)
{
    vector< vector< pair<int, int> > > rmq(out.size());
    size_t lg = static_cast<size_t>(log(out.size())/log(2)) + 1;

    for (vector< vector< pair<int, int> > >::iterator it = rmq.begin();
         it != rmq.end(); ++it)
        it->reserve(lg);

    for (size_t i = 0; i < rmq.size(); ++i)
        rmq[i][0] = out[i];

    for (size_t i = 1; i < lg; ++i)
        for (size_t j = 0; j + (1 << i) - 1 < rmq.size(); ++j)
            rmq[j][i] = min(rmq[j][i - 1], rmq[j + (1 << (i - 1))][i - 1]);

    return rmq;
}


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

    int N, M;
    fin >> N >> M;

    vector< list<int> > adj(N);
    for (int i = 2; i <= N; ++i) {
        int x;
        fin >> x;

        adj[x - 1].push_back(i - 1);
    }

    vector< pair<int, int> > output;
    vector<int> first_idx(N);
    getEulers(0, 0, adj, output, first_idx);

    vector< vector< pair<int, int> > > rmq = getRmq(output);
    for (; M--;) {
        int x, y;
        fin >> x >> y;
        --x, --y;

        int i = first_idx[x];
        int j = first_idx[y];
        if (i > j) {
            int tmp = i;
            i = j;
            j = tmp;
        }

        size_t k = static_cast<size_t>(log(j - i + 1)/log(2));
        fout << min(rmq[i][k], rmq[j - (1 << k) + 1][k]).second  + 1 << "\n";
    }

    fin.close();
    fout.close();
    return 0;
}