Cod sursa(job #2808903)

Utilizator natrovanCeval Marius natrovan Data 25 noiembrie 2021 17:19:37
Problema Range minimum query Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.21 kb
#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

#define MAX_INT 2147483647

void read_vector(vector<int> &v, int n)
{
    for (int i = 0; i < n; i++)
    {
        int x;
        cin >> x;
        v.push_back(x);
    }
}

void build_sparse_table(vector<int> &sparse, vector<int> &v)
{
    int n = v.size();
    int sparse_piece = floor(sqrt(n));
    int min_num = MAX_INT;

    for (int i = 0; i < n; i++)
    {
        if (v[i] < min_num)
            min_num = v[i];

        if ((i + 1) % sparse_piece == 0)
        {
            sparse.push_back(min_num);
            min_num = MAX_INT;
        }
    }

    if (n % sparse_piece)
    {
        sparse.push_back(min_num);
    }
}

int min_interval_linear(vector<int> &v, int left, int right)
{
    if (left > right)
        return MAX_INT;

    if (left < 0)
        left = 0;

    if (right >= (int)v.size())
        right = v.size() - 1;

    int min_num = v[left];
    for (int i = left; i <= right; i++)
    {
        if (min_num > v[i])
            min_num = v[i];
    }
    return min_num;
}

void query(vector<int> v, vector<int> &sparse, int left, int right)
{
    int sparse_piece = floor(sqrt(v.size()));
    int sparse_left = ceil((float)left / sparse_piece);
    int sparse_right = floor(((float)right / sparse_piece) - 1);

    int query_min;
    if (sparse_left >= sparse_right)
    {
        query_min = min_interval_linear(v, left, right);
        cout << query_min << '\n';
        return;
    }

    query_min = min_interval_linear(sparse, sparse_left, sparse_right);

    query_min = min(
        query_min,
        min_interval_linear(v, left, sparse_left * sparse_piece));

    query_min = min(
        query_min,
        min_interval_linear(v, (sparse_right + 1) * sparse_piece - 1, right));

    cout << query_min << '\n';
}

void read_query(vector<int> &v, vector<int> &sparse, int m)
{
    for (int i = 0; i < m; i++)
    {
        int left, right;
        cin >> left >> right;
        left--;
        right--;
        query(v, sparse, left, right);
    }
}

int main()
{
    int n, m;
    cin >> n >> m;

    vector<int> v;
    read_vector(v, n);

    vector<int> sparse;
    build_sparse_table(sparse, v);

    read_query(v, sparse, m);

    return 0;
}