Cod sursa(job #2900816)

Utilizator maria-marianita.cucos@s.unibuc.roCucos Marianita [email protected] Data 12 mai 2022 10:19:26
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.45 kb
//// C++ program to do range
//// minimum query in O(1) time with
//// O(n*n) extra space and O(n*n)
//// preprocessing time.
//#include <bits/stdc++.h>
//using namespace std;
//
//#define MAX 500
//
//#include <fstream>
//ifstream f("rmq.in");
//ofstream g("rmq.out");
//
//// lookup[i][j] is going to store
//// index of minimum value in
//// arr[i..j]
//int lookup[MAX][MAX];
//
//// Structure to represent a query range
//struct Query {
//    int L, R;
//}q[1000];
//
//// Fills lookup array lookup[n][n]
//// for all possible values
//// of query ranges
//void preprocess(int arr[], int n)
//{
//    // Initialize lookup[][] for the
//    // intervals with length 1
//    for (int i = 1; i <= n; i++)
//        lookup[i][i] = i;
//
//    // Fill rest of the entries in bottom up manner
//    for (int i = 1; i <= n; i++) {
//        for (int j = i + 1; j <= n; j++)
//
//            // To find minimum of [0,4],
//            // we compare minimum
//            // of arr[lookup[0][3]] with arr[4].
//            if (arr[lookup[i][j - 1]] < arr[j])
//                lookup[i][j] = lookup[i][j - 1];
//            else
//                lookup[i][j] = j;
//    }
//}
//
//// Prints minimum of given m
//// query ranges in arr[0..n-1]
//void RMQ(int arr[], int n, Query q[], int m)
//{
//    // Fill lookup table for
//    // all possible input queries
//    preprocess(arr, n);
//
//    // One by one compute sum of all queries
//    for (int i = 0; i < m; i++)
//    {
//        // Left and right boundaries
//        // of current range
//        int L = q[i].L, R = q[i].R;
//
//        // Print sum of current query range
//        g << arr[lookup[L][R]] << endl;
//    }
//}
//
//// Driver code
//int main()
//{
////    int a[] = { 7, 2, 3, 0, 5, 10, 3, 12, 18 };
////    int n = sizeof(a) / sizeof(a[0]);
////    Query q[] = { { 2, 4 }, { 1, 2 }, { 3, 5 }, { 1, 4 } };
////    int m = sizeof(q) / sizeof(q[0]);
////    RMQ(a, n, q, m);
//    int N,M,v[1000];
////    Query q;
//    f>>N>>M;
//
//    for (int i = 1; i <= N; ++i) {
//        f>>v[i];
//    }
//
//    for (int i = 0; i < M; ++i) {
//        f>>q[i].L>>q[i].R;
//    }
//    f.close();
//    RMQ(v,N,q,M);
////    cout<<"am citit";
//    return 0;
//}

#include <iostream>
#include <fstream>
#include <math.h>

using namespace std;

ifstream in("rmq.in");
ofstream out("rmq.out");

int v[100100], bucketMinPoz[100100][20], k, i, j, n, m, x, y, p; //retinem poz minimului din v in bucketul actual

void creeazaBucketuri()
{
    for(i = 0; i < n ; i++)
        bucketMinPoz[i][0] = i;

    for(j = 1; (1 << j) <= n; j++)
        for(i = 0; i + (1 << j) - 1 < n; i++)
            if(v[bucketMinPoz[i][j - 1]] < v[bucketMinPoz[i + (1 << (j - 1))][j - 1]])
                bucketMinPoz[i][j] = bucketMinPoz[i][j - 1];
            else
                bucketMinPoz[i][j] = bucketMinPoz[i + (1 << (j - 1))][j - 1];
}

int main()
{
    in>>n>>m;

    for(i = 0; i < n; i++)
        in>>v[i];

    creeazaBucketuri();

    for(i = 1; i <= m; i++)
    {
        in>>x>>y;

        p = 1;
        k = 0;
        while(p * 2 <= y - x + 1)      //k = log(j - i + 1)
        {
            p *= 2;
            k++;
        }

        if(v[bucketMinPoz[x - 1][k]] <= v[bucketMinPoz[y - p][k]])
            out<<v[bucketMinPoz[x - 1][k]]<<'\n';
        else
            out<<v[bucketMinPoz[y - p][k]]<<'\n';
    }

    return 0;
}