Cod sursa(job #3207279)

Utilizator Alexia_CiobanuAlexia Maria Ciobanu Alexia_Ciobanu Data 25 februarie 2024 18:37:30
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.38 kb
#include <fstream>
#define NMAX 1000002
#define LOG 20
using namespace std;
ifstream fin ("rmq.in");
ofstream fout("rmq.out");

int v[NMAX],n;
int q;
int dp[NMAX][LOG]; ///dp[i][j]- INDEXUL elementului minim secv care incepe cu i si are lungimea 2^j
int rmq(int x, int y)
{
    if(y<x) swap(x,y);
    int k=y-x+1;
    int i=1;
    while((1<<i)<=k) i++;
    k=i-1;
    int dif= y-( x+(1<<k) );
    /// x+ y - x -2^k  = y - 2^k => y - 2^k +1 , ..... y = 2^k elemente
    return min(v[dp[x][k]],v[dp[x+dif+1][k]]);
}
int main()
{
    fin>>n>>q;
    for(int i=1;i<=n;i++) fin>>v[i];
    for(int i=1;i<=n;i++) dp[i][0]=i; ///secv 1 cu lungime 2^0= INDEXUL elementului insusi
    for(int j=1;(1<<j)<=n;j++)
        for(int i=1;i<=n-(1<<j)+1;i++)
            {                   ///i+2^(j-1)+2^(j-1)= i+2^j-
                if(v[dp[i][j-1]]<=v[dp[i+( 1<<(j-1) )][j-1]])
                    dp[i][j]=dp[i][j-1];
                else
                    dp[i][j]=dp[i+( 1<<(j-1) )][j-1];
            }
    ///explicatii: secv i cu lungime 2^j =>
                     ///i, i+1,.............................., i-2+2^j, i-1+2^j
    /// dp[i][j-1]= min i, i+1,...,i-1+2^(j-1).
    ///dp[i-1+1<<(j-1)][j-1]= min             ,i+2^(j-1),....,i-2+2^j, i-1+2^j

    for(int i=1;i<=q;i++)
    {
        int a,b;
        fin>>a>>b;
        fout<<rmq(a,b)<<'\n';
    }
    return 0;
}