RMQ (ST)

 

//  RMQ Sparse Table.cpp : 定义控制台应用程序的入口点。
//  RMQ  RMQ(i,j)从i到j区间的最小值 M[i][k] 表示i开始(包含i)到i-1+1<<k 的最小值
//  k=log(j-i+1); RMQ(i,j) = MMIN(M[i][k],M[j+1-(1<<k)][k])
//  即把(i,j)这个区间分成(i,i-1+1<<k)和(j+1-1<<k,j)

#include 
" stdafx.h "
#include
< iostream >
#include
< cmath >
using   namespace  std;
#define  MAXN 310
#define  LOGMAXN  int(log(1000000+1.0)/log(2.0))
int  M1[MAXN][ 20 ];  //  20 = LOGMAXN
int  A[MAXN];
int  N,M;
int  A2[MAXN][MAXN];
int  M2[MAXN][MAXN][ 9 ][ 9 ];   // p=9= LOGMAXN_ROW q=9= LOGMAXN_column
//  *********** 一维 ************* //
inline  int   MMIN( int  a, int  b)
{
    
if(a > b) return b;
    
else return a;
}

void  process1()
{
    
int i,j;
    
for(i = 0; i < N; i++)
        M1[i][
0= A[i];
    
for(j = 11 << j <= N; j++)
    
{
        
for(i = 0; i + (1 << (j-1)) -1 <N ; i++)
        
{
            
if( M1[i][j-1< M1[i + (1 << (j - 1))][j-1])
                M1[i][j] 
= M1[i][j-1];
            
else 
                M1[i][j] 
= M1[i + (1 << (j - 1))][j-1];
        }

    }

}

int  query( int  low, int  high)
{
    
int k=log(high-low+1.0)/log(2.0);
    
if(M1[low][k] < M1[high + 1 - (1 << k)][k])
        
return M1[low][k];
    
else return M1[high + 1 - (1 << k)][k];
}

//  ************** 一维结束 ************** //


//  ************** 二维 ***************** //
void  process2()
{
    
int i,j,p,q;
    
for(i = 0;i < N;i++)
        
for(j = 0;j < M; j++)
            M2[i][j][
0][0= A2[i][j];
    
for(p = 0;1 << p <= N; p++)
    
{
        
for(q=01 << q <=M; q++)
        
{
            
if(p == 0 && q == 0continue;
            
for(i = 0; i + (1 << p) - 1 < N ; i++)
            
{
                
for(j = 0; j + (1 << q) -1 < M ; j++)
                
{
                    
if(p == 0
                    
{
                        
//if(M2[i][j][p][q-1] < M2[i][j + (1 << (q-1))][p][q-1])
                        
//    M2[i][j][p][q] = M2[i][j][p][q-1];
                        
//else 
                        
//    M2[i][j][p][q] =  M2[i][j + (1 << (q-1))][p][q-1];
                        M2[i][j][p][q] = MMIN(M2[i][j][p][q-1],M2[i][j + (1 << (q-1))][p][q-1]);
                    }

                    
else 
                    
{
                           
//if(M2[i][j][p-1][q] < M2[i + (1 << (p-1)) ][j][p-1][q])
                        
//  M2[i][j][p][q] = M2[i][j][p-1][q];
                        
//else 
                        
//    M2[i][j][p][q] = M2[i + (1 << (p-1)) ][j][p-1][q];
                        M2[i][j][p][q] = MMIN(M2[i][j][p-1][q],M2[i + (1 << (p-1))][j][p-1][q]);
                        
                    }

                }

            }

        }

    }

}


int  query( int  low_x, int  low_y, int  high_x,  int  high_y)
{
    
int k_x = log(high_x - low_x + 1.0/ log(2.0);
    
int k_y = log(high_y - low_y + 1.0/ log(2.0);
    
return MMIN( MMIN(    MMIN( M2[low_x][low_y][k_x][k_y] , M2[high_x - (1 << k_x) + 1][high_y - (1 << k_y) + 1][k_x][k_y]) ,    M2[low_x][high_y - (1 << k_y) +1][k_x][k_y]) , M2[high_x - (1 << k_x) +1][low_y][k_x][k_y] );
}

int  main()
{
    
int t,i,j,x,y,x1,y1,q;
    scanf(
"%d",&t);
    
while(t--)
    
{
        scanf(
"%d",&N);
        M 
= N;
        
for(i=0;i<N;i++)
            
for(j=0;j<M;j++)
                scanf(
"%d",&A2[i][j]);
        scanf(
"%d",&q);
        process2();
        
for(i=0;i<q;i++)
        
{
            scanf(
"%d %d %d %d",&x,&y,&x1,&y1);
            printf(
"%d ",query(x-1,y-1,x1-1,y1-1));
        }

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值