Cod sursa(job #2752996)

Utilizator Andreea__Zavoiu Andreea Andreea__ Data 20 mai 2021 17:36:06
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.07 kb
#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("rmq.in");
ofstream fout("rmq.out");

/// => Arbori de Intervale (Segment Tree)  -> in fiecare nod retin minimul fiilor (frunzele iau valorile elementelor vectorului dat) => in varf voi avea minul
// dimensiunea de siguranta este 4*n => 4*100 000
// pt nodul i, fii sunt 2*i+1 si 2*i+2

int stree[400000], v[100000];

void constructST(int i, int st, int dr) {
    if (st == dr) {
        stree[i] = v[dr];
        return;
    }

    int mij = (st + dr) / 2;
    constructST (2*i+1, st, mij ); // fiul stang
    constructST (2*i+2, mij + 1, dr ); // fiul drept

    stree[i] = min( stree[2*i+1], stree[2 * i + 2] ); // in nod se alege minimul dintre cei 2 fii
}

int RMQ(int i, int st, int dr, int x, int y)
{
    // If segment of this node is a part of the given range, then return the min of the segment
    if (x <= st && y >= dr)
        return stree[i];

    // If a part of this segment overlaps with the given range
    int mij = st + (dr - st) / 2;

    /*// If segment of this node is outside the given range
    if (dr < x || st > y)
        return 100005;  // cea mai mare val posibila, sa ma asigur ca nu va fi considerat nod minim */

    if (x > mij)
        return RMQ(2 * i + 2, mij + 1, dr, x, y);
    else if (y <= mij)
        return RMQ(2 * i + 1, st, mij, x, y);

    return min( RMQ(2*i+1, st, mij, x, mij),  RMQ(2*i+2, mij+1, dr, mij+1, y) );
}

int main()
{
    int n, m, x, y;
    fin >> n >> m;

    // in exemplu, indexarea se face de la 1 la n... => si arborele il voi indexa tot incepand de la 1
    for (int i=1; i<=n; i++)
        fin >> v[i];

    constructST(1, 1, n); // construiesc arborele de intervale incepand cu nodul 1, pentru intervalul [1,n]

    for (int i = 0; i < m; i++) {   // citesc cele m intervale si afisez minimul pt fiecare
            fin >> x >> y;
            fout << RMQ(1, 1, n, x, y) << '\n';
        }

    return 0;
}

// ajutor la implementare: https://www.geeksforgeeks.org/segment-tree-set-1-range-minimum-query/