POJ 3264 Balanced Lineup

  
    
/*
RMQ问题——稀疏表算法
状态转移方程
dp[i,j]=min{dp[i,j-1],dp[i+2j-1,j-1]}
*/
#include
< stdio.h >
#include
< math.h >
#include
< stdlib.h >
const int MAXN = 50001 ;
int max[MAXN][ 16 ],min[MAXN][ 16 ]; // 2^16 = 65536
int a[MAXN];
int n, Q;
inline
int getMax( int a, int b){
return a > b ? a : b;
}
inline
int getMin( int a, int b){
return a < b ? a : b;
}
void RMQ_init(){
int i, j, m;
for (i = 1 ; i <= n; i ++ )
max[i][
0 ] = min[i][ 0 ] = a[i]; // i ~ i*2^0 即a[i]
m = ( int )(log(( double )n) / log( 2.0 ));
for (j = 1 ; j <= m; ++ j){ // 自底向上递推
for (i = n; i > 0 ; i -- ){
max[i][j]
= getMax(max[i][j - 1 ], max[i + ( 1 << (j - 1 ))][j - 1 ]);
min[i][j]
= getMin(min[i][j - 1 ], min[i + ( 1 << (j - 1 ))][j - 1 ]);
}
}
}
int findMax( const int f, const int t){
if ( f == t )
return max[f][ 0 ];
int m = ( int )(log(( double )(t - f + 1 )) / log( 2.0 ));
return getMax(max[f][m], max[t + 1 - ( 1 << (m))][m]);
}
int findMin( const int f, const int t){
if ( f == t )
return min[f][ 0 ];
int m = ( int )(log(( double )(t - f + 1 )) / log( 2.0 ));
return getMin(min[f][m], min[t + 1 - ( 1 << (m))][m]);
}
int main(){
int f, t;
scanf(
" %d%d " , & n, & Q);
for ( int i = 1 ; i <= n; ++ i)
scanf(
" %d " , & a[i]);
RMQ_init();
for ( int i = 0 ; i < Q; ++ i){
scanf(
" %d%d " , & f, & t);
if (f > t)
f
^= t ^= f ^= t;
printf(
" %d\n " , findMax(f, t) - findMin(f, t));
}
return 0 ;
}

你可能感兴趣的:(poj)