Cod sursa(job #1811193)

Utilizator RadduFMI Dinu Radu Raddu Data 20 noiembrie 2016 22:04:17
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.26 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <bitset>
#include <algorithm>
#define NMAX 200003
#define LMAX 20

using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
vector <int> G[NMAX];
stack <int> st;
bitset <NMAX> mark;
int N, M;
int height[NMAX], euler_n[2 * NMAX], euler_h[2 * NMAX];
int pos[NMAX], lg[2 * NMAX];
int sp[LMAX][NMAX];

void dfs()
{
    st.push(1);
    mark.set(1);
    int top, node, ok;
    while (!st.empty())
    {
        top = st.top();
        ok = 0;
        euler_n[++euler_n[0]] = top;
        for (unsigned int i = 0; i < G[top].size(); i++)
            if (!mark.test(G[top][i]))
            {
                node = G[top][i];
                ok = 1;
                break;
            }
        if (ok)
        {
            st.push(node);
            mark.set(node);
            height[node] = height[top] + 1;
        }
        else
            st.pop();
    }
}

void sparse_table()
{
    int dim = euler_n[0];
    for (int i = 2; i <= dim; i++)
        lg[i] = lg[i / 2] + 1;
    for (int i = 1; i <= dim; i++)
        sp[0][i] = i;
    for (int i = 1; (1 << i) <= dim; i++)
        for (int j = 1; j + (1 << i) - 1 <= dim; j++)
            if (euler_h[sp[i - 1][j]] <= euler_h[sp[i - 1][j + (1 << (i - 1))]])
                sp[i][j] = sp[i - 1][j];
            else
                sp[i][j] = sp[i - 1][j + (1 << (i - 1))];
}

int main()
{
    in >> N >> M;
    int x, y;
    for (int i = 2; i <= N; i++)
    {
        in >> x;
        G[x].push_back(i);
    }
    dfs();
    euler_h[0] = euler_n[0];
    for (int i = 1; i <= euler_n[0]; i++)
    {
        euler_h[i] = height[euler_n[i]];
        if (pos[euler_n[i]] == 0)
            pos[euler_n[i]] = i;
    }
    sparse_table();
    int k, lca;
    for (int i = 1; i <= M; i++)
    {
        in >> x >> y;
        x = pos[x];
        y = pos[y];
        if (x > y)
            swap(x, y);
        k = lg[y - x + 1];
        if (euler_h[sp[k][x]] <= euler_h[sp[k][y - (1 << k) + 1]])
            lca = euler_n[sp[k][x]];
        else
            lca = euler_n[sp[k][y - (1 << k) + 1]];
        out << lca << "\n";
    }
    in.close();
    out.close();
    return 0;
}