Cod sursa(job #3181608)

Utilizator razviOKPopan Razvan Calin razviOK Data 7 decembrie 2023 14:58:09
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.33 kb
#include <stdio.h>
#include <stdlib.h>

int Minimum(int a,int b){
    return (a<b) ? a:b;
}
void DynamicProgrammingSolution(int *arr,int N,int M) {

    int **Dp = (int **) malloc(sizeof(int *) * N);
    for (int i = 0; i < N; i++) {
        Dp[i] = (int *) malloc(sizeof(int) * (N - i));
    }

    for (int i = 0; i < N; i++)
        for (int j = 0; j < N - i; j++) {
            if (j == 0) Dp[i][j] = arr[i];
            else Dp[i][j] = Minimum(Dp[i][j - 1], arr[i+j]);
        }
//    for (int i = 0; i < N; i++){
//        for (int j = 0; j < N - i; j++)
//            printf("%d ",Dp[i][j]);
//        printf("\n");
//}


    int a,b;
    for(int i=0;i<M;i++){
        scanf("%d",&a);
        scanf("%d",&b);
        printf("%d\n",Dp[a-1][b-a]);
    }

    for(int i=0;i<N;i++) {
        free(Dp[i]);
    }

    free(Dp);



}
void SquareRootDecomposition(int *arr,int N,int M){

    int square_root,size;
    for(square_root=1;square_root*square_root<=N;square_root++);
    square_root--;
    //printf("%d",square_root);
    size=square_root;

    if(square_root*square_root!=N)
        size++;


    int *SqrArr = (int *) malloc(sizeof(int) * size);

    int cnt=-1;
    for(int i=0;i<N;i++){
     if(i%square_root==0){
         cnt++;
         SqrArr[cnt]=arr[i];
     }
     else SqrArr[cnt]= Minimum(SqrArr[cnt],arr[i]);
    }

    int a,b,min=(~0)^(1<<31);
    for(int q=0;q<M;q++){
        min=(~0)^(1<<31);
        scanf("%d",&a);
        scanf("%d",&b);
        a-=1;
        b-=1;
        for(int it=a;it<=b;it++){
            if(it%square_root==0 && it+square_root-1<=b) {
                min = Minimum(min, SqrArr[it/square_root]);
                it+=square_root;
                it--;
            }
            else min= Minimum(min,arr[it]);
        }
        printf("%d\n",min);

    }

//    for(int i=0;i<size;i++)
//        printf("%d ",SqrArr[i]);
    free(SqrArr);
}
void RangeMinimumQuery(int *arr,int N,int M){

    int log,aux,aux2,a,b;
    for(aux=N;aux>0;aux>>=1,log++);
   // printf("%d\n",log);

    int **RMQ=(int **) malloc(sizeof(int *)*log);
    aux=1;
    for(int i=0;i<log;i++){
        RMQ[i]=(int *) malloc(sizeof(int)*(N-aux+1));
        aux<<=1;
    }

    aux=1;
    for(int i=0;i<log;i++) {
        aux2=aux;
        aux2>>=1;
        for (int j = 0;j<N-aux+1;j++){
          RMQ[i][j]= (i==0) ? j:(arr[RMQ[i-1][j]]<arr[RMQ[i-1][j+aux2]]) ? RMQ[i-1][j]:RMQ[i-1][j+aux2];
        }
        aux<<=1;
    }

     int k,expk=1;
    for(int q=0;q<M;q++){
        scanf("%d",&a);
        scanf("%d",&b);
        a-=1;
        b-=1;
        expk=1;
        k=0;
        for(int i=b-a+1;i>0;i>>=1,k++);
        k--;
        for(int i=0;i<k;i++,expk<<=1);


        printf("%d\n", Minimum(arr[RMQ[k][a]],arr[RMQ[k][b-expk+1]]));
    }
//    aux=1;
//    for(int i=0;i<log;i++) {
//        for (int j = 0;j<N-aux+1;j++){
//            printf("%d ",RMQ[i][j]);
//        }
//        printf("\n");
//        aux<<=1;
//    }

     for(int i=0;i<log;i++)
        free(RMQ[i]);

    free(RMQ);
}
int main() {

    freopen("rmq.in","r",stdin);
    freopen("rmq.out","w",stdout);

    int N,M;
    scanf("%d",&N);
    scanf("%d",&M);
    int *arr=(int *) malloc(sizeof(int)*N);
    for(int i=0;i<N;i++)
        scanf("%d",&arr[i]);

    //DynamicProgrammingSolution(arr,N,M);
    //SquareRootDecomposition(arr,N,M);
    RangeMinimumQuery(arr,N,M);

    free(arr);
    return 0;
}