/*
* 定义f(i,j)为区间[i,i+2^j-1]的最小值,即从i开始的长度为2^j的区段
* 其中f[i,0]=a[i]
* 那么对于任意(i,j),令k=lg(j-i+1)/lg2 则查询分成两个部分
* 则2^k<=(j-i+1)且
* 2^(k+1)=2^(lg(j-i+1)/lg2+1)>j-i+1+1
* 从而有 i+2^k-1>j-2^k+1
* 所以只要求出[i,i+2^k-1]和[j-2^k+1,j]区间的最小值就能在o(1)时间内得到
* [i,j]区间的最小值
* f(i,j)=min{f(i,j-1),f(i+2^(j-1),j-1)}
* 这就转化为动态规划问题
* 程序没有调试,只是个说明
*/
#include <iostream>
#include <math.h>
#include <stdlib.h>
using namespace std;
int **dp_max;
int **dp_min;
static void make_big_rmq(int *n,int len)
{
int i,j,dim,k;
dim=(int)floor(log((double)len)/log(2.0));
for(i=0;i<len;i++)
dp_max[i][0]=a[i];
for(j=1;j<=dim;j++)
for(i=0;i+(1<<j)-1<=n;i++){
dp_max[i][j]=max(dp_max[i][j-1],dp_max[i+(1<<(j-1)])][j-1]);
}
}
static void make_small_rmq(int *n,int len)
{
int i,j,dim,k;
dim=(int)floor(log((double)len)/log(2.0));
for(i=0;i<len;i++)
dp_min[i][0]=a[i];
for(j=1;j<=dim;j++)
for(i=0;i+(1<<j)-1<=n;i++){
dp_min[i][j]=max(dp_min[i][j-1],dp_min[i+(1<<(j-1)])][j-1]);
}
}
int main(void)
{
int n[]={19,24,53,1,53,123,34,2,32,12};
int len=sizeof(n)/sizeof(n[0]);
int dim=(int)floor(log((double)len)/log(2.0));
dp_max=(int **)malloc(len*sizeof(int *));
dp_min=(int **)malloc(len*sizeof(int *));
for(i=0;i<len;i++){
dp_max[i]=(int *)malloc(dim*sizeof(int));
dp_min[i]=(int *)malloc(dim*sizeof(int));
}
make_big_rmq(int *n,int len);
make_small_rmq(int *n,int len);
for(i=0;i<len;i++){
free(dp_max[i]);
free(dp_min[i]);
}
free(dp_max);
free(dp_min);
dp_max=dp_min=null;
return 0;
}