RMQ问题 树状数组

用树状数组解决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]);
	}
}


你可能感兴趣的:(算法)