Cod sursa(job #1650914)

Utilizator bullseYeIacob Sergiu bullseYe Data 11 martie 2016 21:30:08
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.97 kb
#include <cstdio>
#include <algorithm>
#define NMAX 100010
using namespace std;
FILE*fin=fopen ("rmq.in", "r");
FILE*fout=fopen ("rmq.out", "w");

int M[NMAX][20];
int A[NMAX];
int n, m, log2n;
void precalculare();
int query (int, int);

int main()
{
    int i, a, b;
    fscanf(fin, "%d %d", &n, &m);
    for (i=1; i<=n; ++i)
        fscanf(fin, "%d", &A[i]);
    precalculare();
    for (i=1; i<=m; ++i)
    {
        fscanf(fin, "%d %d", &a, &b);
        fprintf(fout, "%d\n", query (a, b));
    }
    fclose(fout);
    return 0;
}


//M[i][j]=pozitia elementului minim in vectorul A din subsecventa care incepe la i si are lungimea 2^j
void precalculare()
{
    int i, j;
    for (log2n=0, j=1; j<n; j*=2, ++log2n);
    if ((1<<log2n)-n) --log2n;

    for (i=1; i<=n; ++i)
        M[i][0]=i;
    for (j=1; j<=log2n; ++j)
        for (i=1; i+(1<<j)<=n; ++i)
            if (A[M[i][j-1]]<A[M[i+(1<<(j-1))][j-1]])
                M[i][j]=M[i][j-1];
                else
                M[i][j]=M[i+(1<<(j-1))][j-1];
    return;
}

int query (int st, int dr)
{
    int lg, log2lg, ct;
    lg=dr-st+1;
    for (log2lg=0, ct=1; ct<lg; ct*=2, ++log2lg);
    if ((1<<log2lg)-lg) --log2lg;
    return (min (A[M[st][log2lg]], A[M[dr-(1<<log2lg)+1][log2lg]]));
}

//solutie cu arbori de intervale - 70 de puncte
/*#include <cstdio>
#include <algorithm>
#define NMAX 100010*4
using namespace std;
FILE*fin=fopen ("rmq.in", "r");
FILE*fout=fopen ("rmq.out", "w");


int H[NMAX];
int n, m;
void citire();
void actualizare (int, int, int, int, int);
void query (int, int, int, int, int, int&);

int main()
{
    int i, val;
    int a, b;
    fscanf(fin, "%d %d", &n, &m);
    for (i=1; i<=n; ++i)
    {
        fscanf(fin, "%d", &val);
        actualizare (1, 1, n, i, val);
    }

    for (i=1; i<=m; ++i)
    {
        fscanf(fin, "%d %d", &a, &b);
        val=NMAX;
        query (1, 1, n, a, b, val);
        fprintf(fout, "%d\n", val);
    }
    return 0;
}

void actualizare (int nod, int st, int dr, int where, int val)
{
    int mijl;
    if (st==dr)
    {
        H[nod]=val;
        return;
    }
    //vad unde trebuie sa ma duc acum
    mijl=(st+dr)/2;//st, dr reprezinta intervalul in care ma aflu eu acum
    //where reprezinta intervalul de lungime 1 pe care trebuie sa il modific
    if (where<=mijl)
        actualizare (2*nod, st, mijl, where, val);
        else
        actualizare (2*nod+1, mijl+1, dr, where, val);
    H[nod]=min(H[2*nod], H[2*nod+1]);
    return;
}

void query (int nod, int st, int dr, int left_query, int right_query, int &rez)
{
    int mijl;
    if (left_query<=st && dr<=right_query)
    {
        if (H[nod]<rez)
            rez=H[nod];
        return;
    }
    mijl=(st+dr)/2;
    if (left_query<=mijl)
        query (2*nod, st, mijl, left_query, right_query, rez);
    if (mijl<right_query)
        query (2*nod+1, mijl+1, dr, left_query, right_query, rez);
    return;
}*/