Cod sursa(job #2186438)

Utilizator alisavaAlin Sava alisava Data 25 martie 2018 16:55:42
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.84 kb
#include <bits/stdc++.h>
#define lung(x) ( 1 << x )


using namespace std;

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

int M[100005][20],A[100005], N;
///in M[i][j] tinem pozitia minimului pt intervalul [i,i+lung(j)-1]
inline int log(int x)
{
    int cnt=0;
    while(x!=0)
    {
        x=(x>>1);
        cnt++;
    }
    return cnt-1;
}


void FormareM()
{
      int i,j;
      ///------------------------------------------------
      for (i = 1; i <= N; i++)
          M[i][0] = i;
    ///------------------------------------------------
      for (j=1; lung(j)<= N; j++)
          for (i = 1; i + lung(j) - 1 <= N; i++)
              if (A[M[i][j - 1]] ///minimul primului interval
                  < A[M[i + lung(j-1)] [j - 1]]) ///minimul celui de al 2 lea interval
                  M[i][j] = M[i][j - 1]; /// se atribuiie valoarea primului interval din care se formeaza
              else
                  M[i][j] = M[i+(lung(j-1))][j-1];/// se atribuie valoarea celui de al doilea interval

}

/**
 for (j = 1; 1 << j <= N; j++)
          for (i = 0; i + (1 << j) - 1 < 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];


*/
inline void Query(int i,int j)
{

    int k =log(j - i + 1);
    /// M[i][k] rep minimul pt primul int
    /// M[j-lung(k)+1]][k] rep minimul pt int 2
    ///cele 2 pot fi intersectate
    if(A[M[i][k]]<=A[M[j-lung(k)+1][k]])
        fout<<A[M[i][k]]<<"\n";
    else
        fout<<A[M[j-lung(k)+1][k]]<<"\n";
}




int main()
{
    int q,x,y;
    fin>>N>>q;
    for(int i=1;i<=N;i++)
        fin>>A[i];
    FormareM();
    for(int i=1;i<=q;i++)
    {
        fin>>x>>y;
        Query(x,y);
    }
    return 0;
}