用树状数组解决RMQ问题,请看参考资料,作者用Java实现
参考资料:http://www.cnblogs.com/ljsspace/archive/2011/08/10/2133514.html
下面是仿照用C实现:
#include "stdio.h"
#include "string.h"
#define M 100
#define LOW(p) ((p)&(-(p)))
int t[M], a[M] = { 10,15,34,20,7,5,18,68,29,40, //0..9
24,3,45,26,7,23,43,12,68,34, //10..19
26,34,33,12,80,57,24,42,77,27, //20..29
56,33,23,32,54,13,79,65,19,33, //30..39
15,24,43,73,55,13,63,8,23,17 //40..49
};
int n = 50;
void update(int p){
int k = p-1;
while(p<=n){
if(t[p]==-1 || a[t[p]]>a[k])
t[p] = k;
p += LOW(p);
}
}
void create_0(){
int i;
memset(t, -1, sizeof(t));
for(i=1; i<=n; i++){
update(i);
}
}
void create_1(){
int i, j, k;
for(i=1; i<=n; i++){
t[i] = i-1;
k = LOW(i);
for(j=1; j a[t[i-j]])
t[i] = t[i-j];
}
}
}
void create_2(){
int i, j, z;
for(i=1; i<=n; i++){
t[i] = i-1;
z = i - LOW(i);
for(j=i-1; j>z; j-=LOW(j)){
if(a[t[i]] > a[t[j]])
t[i] = t[j];
}
}
}
int query(int p, int q, int min){
int z = q - LOW(q);
if(p>q) return min;
if(p>z){
if(a[q-1] <= a[min])
min = q-1;
return query(p, q-1, min);
}else{
if(a[t[q]] <= a[min])
min = t[q];
return query(p, z, min);
}
}
void main(){
int i, min, s[4]={0, 12, 20, 20}, e[4]={10, 49, 46, 49};
create_0();
// create_1();
// create_2();
for(i=0; i<4; i++){
min = query(s[i]+1, e[i]+1, e[i]-1);
printf("RMQ for A[%3d..%3d]: A[%3d]=%3d%n\n", s[i], e[i], min, a[min]);
}
}