Cod sursa(job #2755476)

Utilizator mariusn01Marius Nicoli mariusn01 Data 27 mai 2021 13:49:16
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.16 kb
#include <iostream>
#include <fstream>

using namespace std;
int D[18][100010];
/**
D[i][j] = minimul dintr-o secventa de lungime 2 la i care incepe la pozitia
j in vectorul dat
practic noi precalculam minime din orice secventa posibila de lungime putere de 2
din vectorul dat

din ce aratam in continoare obtinem ca orice secventa de orice lungime
se poate compune din 2 secvente de lungime putere de 2

**/
int n, i, j, m, st, dr;
int p[18];
int lg[100010];
/// lg[i] = cel mai mare exponent al unei puteri de 2 mai mici sau egale cu i

int main () {
    ifstream fin ("rmq.in");
    ofstream fout("rmq.out");

    fin>>n>>m;
    for(i=1;i<=n;i++)
        fin>>D[0][i];

    p[0] = 1;
    for (i=1;i<=18;i++)
        p[i] = 2*p[i-1]; /// p[i] = 2 la puterea i

    lg[1] = 0;
    for (i=2;i<=n;i++)
        lg[i] = 1 + lg[i/2];

    for (i=1;p[i]<=n;i++)
        /// calculez linia i in functie de linia i-1
        for (j=1;j<=n;j++) {
            D[i][j] = D[i-1][j];
            if (j+p[i-1] <= n && D[i][j] > D[i-1][ j+p[i-1] ])
                D[i][j] = D[i-1][ j+p[i-1] ];
        }

    for (i=1;i<=m;i++) {
        fin>>st>>dr;

        int e = lg[dr-st+1];

        /**
        L = dr-st+1;
        e = 1;
        while (p[e+1] <= L)
            e++;
        **/

        /// calculez e = exeponentul celei mai mari puteri de 2
        /// mai mica sau egala decat dr-st+1 (adica decat lungimea
        /// intervalului dat)
        /// atunci minimul din intervalul st, dr (care nu este neaparat)
        /// putere de 2, il pot exprima in functie de minimul din doua
        /// intervale care au lungime putere de 2 si anume:
        /// - cel care incepe la pozitia st si are lungimea 2 la e
        /// - cel care se termina la pozitia dr si are lungimea 2 la e
        /// 2 la e fiind mai mare ca jumatate din lungimea intervaluluui
        /// st, dr inseamna ca cele 2 intervale descrise mai sus se pot
        /// suprapune pe undeva la mijloc dar acest lucru nu incurca
        fout<<min(D[e][st], D[e][dr-p[e]+1])<<"\n";
    }
    return 0;
}

/**
x x x x x x x x x x
z z z z z z z z
    z z z z z z z z

**/