Cod sursa(job #1196860)

Utilizator RazvanR104Razvan-Andrei Ciocoiu RazvanR104 Data 9 iunie 2014 14:05:12
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2 kb
#include <iostream>
#include <iomanip>
#include <fstream>

#include <algorithm>
#include <bitset>
#include <deque>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#if __cplusplus > 199711L
#include <unordered_map>
#include <unordered_set>
#endif

#include <cstdio>
#include <ctime>
#include <cmath>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef long long int64;

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

const int NMAX = 100010, LOG = 18;

int N, M;
int RMQ[2 * NMAX][LOG], first[NMAX];

vector<int> G[NMAX], nodes, level;

inline int pow2(const int exp) { return (1 << exp); }
inline int log2(int value)
{
    int ret = -1;
    for ( ; value; value >>= 1, ++ret);
    return ret;
}

void DF(const int node, const int lvl)
{
    nodes.push_back(node);
    level.push_back(lvl);
    first[node] = nodes.size() - 1;

    for (size_t it = 0; it < G[node].size(); ++it)
    {
        DF(G[node][it], lvl + 1);

        nodes.push_back(node);
        level.push_back(lvl);
    }
}

int main()
{
    int i, j, x, y;

    fin >> N >> M;

    for (i = 2; i <= N; ++i)
    {
        fin >> x;
        G[x].push_back(i);
    }

    DF(1, 0);

    for (i = 0; i < (int)nodes.size(); ++i)
        RMQ[i][0] = i;

    for (j = 1; pow2(j) <= (int)nodes.size(); ++j)
        for (i = 0; i + pow2(j) - 1 < (int)nodes.size(); ++i)
            if (level[RMQ[i][j - 1]] < level[RMQ[i + pow2(j - 1)][j - 1]])
                RMQ[i][j] = RMQ[i][j - 1];
            else RMQ[i][j] = RMQ[i + pow2(j - 1)][j - 1];

    while(M--)
    {
        fin >> x >> y;
        if (first[x] > first[y]) swap(x, y);
        x = first[x], y = first[y];
        int k = log2(y - x + 1);

        fout << ((level[RMQ[x][k]] < level[RMQ[y - pow2(k) + 1][k]]) ? (nodes[RMQ[x][k]]) : (nodes[RMQ[y - pow2(k) + 1][k]])) << '\n';
    }

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