Cod sursa(job #2755612)

Utilizator AlexSerban21Serban Alexandru AlexSerban21 Data 27 mai 2021 19:32:43
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.19 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
{1}
din ce aratam in continoare obtinem ca orice secventa de orice lungime
se poate compune din 2 secvente de lungime putere de 2
{1}
**/
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
{1}
**/