RMQ 问题集合

题目描述
有一座延绵不断、跌宕起伏的山,最低处海拔为0,最高处海拔不超过8848米,从这座山的一端走到另一端的过程中,每走1米海拔就升高或降低1米。有Q个登山队计划在这座山的不同区段登山,当他们攀到各自区段的最高峰时,就会插上队旗。请你写一个程序找出他们插旗的高度。

注意,起点为0,所以n应该++一下,常数上,st表比线段树慢了大概5倍吧。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005000;
int st[maxn][24];
int n;
void init()
{
	for(int j = 1;(1<<j) <= n;j++){
		for(int i = 1;i+(1<<j)-1 <= n;i++){
			st[i][j] = max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
		}
	}
}
int query(int l,int r){
	int k = 0;
	for(k = 0;(1<<(k+1))<=(r-l+1);k++);
	return max(st[l][k],st[r-(1<<k)+1][k]);
}
int main()
{
	freopen("climb.in","r",stdin);
	freopen("climb.out","w",stdout);
	scanf("%d",&n);
	n++;
	for(int i = 1;i <= n;i++) scanf("%d",&st[i][0]);	
	init();
	int m;
	scanf("%d",&m);
	for(int i = 1;i <= m;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		l++;r++;
		if(l > r) swap(l,r);
		printf("%d\n",query(l,r));
	}	
	return 0;
}
posted @ 2017-07-20 22:40  rsqppp  阅读(117)  评论(0)    收藏  举报