Cod sursa(job #1753024)

Utilizator meriniucrMeriniuc Razvan- Dumitru meriniucr Data 5 septembrie 2016 18:20:32
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.1 kb
#include <fstream>
#include <iostream>
#include <vector>

std::vector <int>   v[100001];
int                 l[200005];
int                 e[200005];
int                 pos[100001];
int                 mins[100001][20];
int                 lg[200005];
int                 j;
int n;

void
min()
{
    int index;
   
    for (index = 1; index <= 2 * n - 1; ++index)
    {
        mins[index][0] = index;
    }

    for (j = 1; (1 << j) < 2 * n - 1; ++j)
    {
        for (index = 1; index < 2 * n - 1; ++index)
        {
            if (index + (1 << j) > 2 * n - 1)
            {
                break;
            }

            if (l[mins[index + (1 << (j - 1))][j - 1]] < l[mins[index][j - 1]])
            {
                mins[index][j] = mins[index + (1 << (j - 1))][j - 1];
            }
            else
            {
                mins[index][j] = mins[index][j - 1];
            }
        }
    }
}

void
build(int node,
      int level)
{
    unsigned int i;

    if (not pos[node])
    {
        pos[node] = j;
    }

    e[j] = node;
    l[j] = level;
    ++j;
    for (i = 0; i < v[node].size(); ++i)
    {
        build(v[node][i],
              level + 1);
        e[j] = node;
        l[j] = level;
        ++j;
    }
}

int main()
{
    std::ifstream mama("lca.in");
    std::ofstream tata("lca.out");

    int m;
    int index;
    int p;
    int temp;

    mama >> n >> m;
    for (index = 2; index <= n; ++index)
    {
        mama >> p;

        v[p].push_back(index);
    }

    j = 1;
    build(1, 0);
    min();

    lg[1] = 0;
    for (index = 2; index < 2 * n; ++index)
    {
        lg[index] = lg[index >> 1] + 1;
    }

    for (index = 0; index < m; ++index)
    {
        mama >> p >> j;

        if (pos[p] > pos[j])
        {
            std::swap(p, j);
        }

        p = pos[p];
        j = pos[j];

        temp = j - p + 1;
        if (l[mins[p][lg[temp]]] < l[mins[j - (1 << lg[temp]) + 1][lg[temp]]])
        {
            tata << e[mins[p][lg[temp]]] << '\n';
        }
        else
        {
            tata << e[mins[j - (1 << lg[temp]) + 1][lg[temp]]] << '\n';
        }
    }
    
    return 0;
}