Cod sursa(job #1585446)

Utilizator dm1sevenDan Marius dm1seven Data 31 ianuarie 2016 00:40:45
Problema Range minimum query Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.59 kb
#include <iostream>
#include <fstream>
using namespace std;
#include <algorithm>
#include <utility>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <map>
#include <set>
#include <stack>
#include <chrono>
using namespace std::chrono;

typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vint;
typedef vector<vint> vvint;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<vvll> vvvll;
typedef vector<ull> vull;
typedef vector<vull> vvull;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef pair<ll, ll> pll;
typedef vector<pll> vpll;

#define fs first
#define sc second
#define pb push_back
// forward strict for, most common
#define fors(i, a, n) for (int i = (int) (a); i < (int) (n); ++i)
// forward inclusive for
#define fori(i, a, n) for (int i = (int) (a); i <= (int) (n); ++i)
// backward for, inclusive
#define forb(i, n, a) for (int i = (int) n; i >= a; --i)

class Problem
{
public:
    int n, t;
    vint a;
    vvint dp;

    void solve()
    {
        ifstream ifs("rmq.in");
        ofstream ofs("rmq.out");

        ifs >> n >> t;
        a.resize(n);
        int log2n = (int) log2(n) + 1;
        dp = vvint(n, vint(log2n + 1));

        fors(i, 0, n)
            ifs >> a[i];

        fors(l, 0, t)
        {
            int p, q;
            ifs >> p >> q;
            int m = min_query(p - 1, q - 1);
            ofs << m << "\n";
        }
    }

    int fdp(int i, int j)
    {
        if (!dp[i][j])
        {
            if (j == 0)
                dp[i][j] = a[i];
            else
            {
                dp[i][j] = fdp(i, j - 1);
                int lu = i + (1 << (j - 1));
                if (lu < n) dp[i][j] = min(dp[i][j], fdp(lu, j - 1));
            }
        }

        return dp[i][j];
    }

    int min_query(int p, int q)
    {
        int s = q - p + 1;
        int p_ = p;
        int m = std::numeric_limits<int>::max();
        while (s != 0)
        {
            int k = binary_zeros(s);
            m = min(m, fdp(p_, k));
            p_ = p_ + (1 << k);
            s -= (1 << k);
        }

        return m;
    }

    int min_bf(int p, int q)
    {
        int m = a[p];
        fori(i, p, q)
            m = min(m, a[i]);
        return m;
    }

    int binary_zeros(int s)
    {
        int k = 0;
        while (s % 2 == 0)
        {
            k++;
            s /= 2;
        }

        return k;
    }
};

int main()
{
    Problem p;
    p.solve();

    return 0;
}