Cod sursa(job #1803843)

Utilizator SlevySlevoaca Stefan-Gabriel Slevy Data 11 noiembrie 2016 22:26:11
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.03 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#define NMAX 100001

using namespace std;

ifstream in("lca.in");
ofstream out("lca.out");
vector <int> G[NMAX];
bitset <NMAX> mark;
stack <int> s;
int euler[2 * NMAX], poz[NMAX], vf = 0;
int height_e[2 * NMAX];
int height[NMAX];
int n, m;
int SP[2 * NMAX][18];
int lg[2 * NMAX];

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

void sparse_table()
{
    for (int i = 2; i <= vf; i++)
        lg[i] = lg[i / 2] + 1;
    for (int i = 1; i <= vf; i++)
        SP[i][0] = i;
    for (int j = 1; (1 << j) <= vf; j++)
        for (int i = 1; i + (1 << j) - 1 <= vf; i++)
            if (height_e[SP[i][j - 1]] < height_e[SP[i + (1 << (j - 1))][j - 1]])
                SP[i][j] = SP[i][j - 1];
            else
                SP[i][j] = SP[i + (1 << (j - 1))][j - 1];
}

int main()
{
    in >> n >> m;
    int x, y;
    for (int i = 1; i <= n-1; i++)
    {
        in >> x;
        G[x].push_back(i + 1);
    }
    dfs();
    sparse_table();
    int k, lca;
    for (int i = 1; i <= m; i++)
    {
        in >> x >> y;
        x = poz[x];
        y = poz[y];
        k = lg[y - x + 1];
        if (SP[x][k] < SP[y - (1 << k) + 1][k])
            lca = euler[SP[x][k]];
        else
             lca = euler[SP[y - (1 << k) + 1][k]];
        out << lca << "\n";
    }
    in.close();
    out.close();
    return 0;
}