Cod sursa(job #2293552)

Utilizator popescu.octavianPopescu Octavian popescu.octavian Data 1 decembrie 2018 04:21:36
Problema Range minimum query Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.63 kb
#include <bits/stdc++.h>
#include <fstream>

#define MIN(a, b) ((a < b) ? a : b)

typedef struct {
    long a;
    long b;
}Query;
/*
    * Avem nevoie de len ca variabila globala,
    * pentru a putea sorta query-urile
*/


int* preprocess(int* arr, int n, int &processedLength) {

    int lastIdx;
    int i;
    int len = (int) sqrt(n);
    int* decomposedMins;

    if (n % len == 0) {
        decomposedMins = (int*) malloc(sizeof(int) * (n/len));
        lastIdx = n/len - 1;
    }
    else {
        decomposedMins = (int*) malloc(sizeof(int) * (n/len + 1));
        lastIdx = n/len;
    }

    for (i = 0; i < n; i += len) {
        //int finalProb = (n - i < len) ? (n - i) : len;
        decomposedMins[i / len] = *std::min_element(arr + i, arr + i + len);
        processedLength++;
    }

    decomposedMins[lastIdx] = *std::min_element(arr + i - len, arr + n);

    return decomposedMins;
}

// bool myCompare(Query q1, Query q2) {

//     if (q1.a / len != q2.a / len) 
//         return q1.a / len < q2.a / len; 
  
//     return q1.b < q2.b; 
// }

// void sortQueries(Query** queries, int noOfQueries) {

//     std::sort (*queries, (*queries) + noOfQueries, myCompare);
// }

void mo(int* arr, Query* queries, int arrLength, int noOfQueries, int* processedMins) {

    int len = (int) sqrt(arrLength);

    for (int i = 0; i < noOfQueries; i++) {

        int L = queries[i].a;
        int R = queries[i].b;

        int lastStandingMin = __INT_MAX__;

        while (L <= R) {
            if ((L % len != 0) || (R - L < len)) {
                lastStandingMin = MIN(lastStandingMin, arr[L]);
                L++;
            } else {
                lastStandingMin = MIN(lastStandingMin, processedMins[L / len]);
                L += len;
            }
        }

    //     int currBlockMinLeftIdx = (int) (L / len);
    //     currBlockMinLeftIdx *= len;

    //     int currBlockMinRightIdx = currBlockMinLeftIdx + len;

    //     // Initializam minimul cu minimul query-ului preprocesat aferent
    //     int lastStandingMin = processedMins[L / len];

    //     // Il comparam pe acesta cu elementele din stanga pe care nu le acopera
    //     while (currBlockMinLeftIdx > L) {
    //         lastStandingMin = MIN(lastStandingMin, arr[L]);
    //         L++;
    //     }

    //     // Il comparam pe acesta cu elementele din dreapta pe care nu le acopera
    //     while (currBlockMinRightIdx < R) {
    //         lastStandingMin = MIN(lastStandingMin, arr[R]);
    //         R--;
    //     }

        printf("%d\n", lastStandingMin);
    }
}

void readInput(int*& arr, int &n, int &noOfQueries, Query*& queries, char const *argv) {

    // FILE* filePtrIn = fopen(argv, "rt");

    // fscanf(filePtrIn, "%d %d", &n, &noOfQueries);

    // arr = (int*) malloc(sizeof(int) * n);
    // queries = (Query*) malloc(sizeof(Query) * noOfQueries);

    // for (int i = 0; i < n; i++)
    //     fscanf(filePtrIn, "%d", (*arr) + i);
    // for (int i = 0; i < noOfQueries; i++) {
    //     fscanf(filePtrIn, "%d", &queries[i].a);
    //     fscanf(filePtrIn, "%d", *((*queries) + i).b));
    // }

    // fclose(filePtrIn);
    std::ifstream fin(argv);

    fin >> n >> noOfQueries;

    arr = (int*) malloc(sizeof(int) * n);
    queries = (Query*) malloc(sizeof(Query) * noOfQueries);

    for (int i = 0; i < n; i++)
        fin >> arr[i];

    //printf("%d %d\n", arr[n - 1], noOfQueries);

    for(int i = 0; i < noOfQueries; i++) {
        fin >> queries[i].a;
        fin >> queries[i].b;
    }
}

int main(int argc, char const *argv[]) {
    // n = 12;
    // int test[] = {2, 5, 3, 2, 1, 0, 9, 7, 1, 1, 3, 0, 1, 0, 3, 1};
    // len = sqrt(10);
    // int processedLength = 0;
    freopen("rmq.out", "rw", stdout);
    int n, noOfQueries, preprocessedLength = 0;
    Query* queries;
    int* arr;

    readInput(arr, n, noOfQueries, queries, "rmq.in");

    // for (int i = 0; i < n; i++) 
    //     printf("%d ", arr[i]);
    // printf("\n");

   int* preprocessedMins = preprocess(arr, n, preprocessedLength);

   mo(arr, queries, n, noOfQueries, preprocessedMins);

    // for (int i = 0; i < processedLength; i++) {
    //     printf("%d ", vrajeala[i]);
    // }
    // printf("\n");

    // Query* queries = (Query*) malloc(sizeof(Query) * 5);
    // queries[0].a = 1;
    // queries[0].b = 3;

    // queries[1].a = 2;
    // queries[1].b = 7;

    // queries[2].a = 5;
    // queries[2].b = 7;

    // queries[3].a = 7;
    // queries[3].b = 11;

    // queries[4].a = 9;
    // queries[4].b = 10;

    // sortQueries(&queries, 5);

    // for (int i = 0; i < 5; i++) {
    //     printf("query[%d].a = %ld  |  query[%d].b = %ld\n", i, queries[i].a, i, queries[i].b);
    // }
    return 0;
}