南邮 OJ 1042 区间最值

区间最值

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 1034            测试通过 : 241 

比赛描述

给定一个长度不超过10000的整数序列,对这个序列有不超过500000个询问,每次询问给定区间之内的最小值.



输入

第一行一个整数N(N<=10000)
第二行N个整数

第三行一个整数Q
以下共Q,每行两个整数i,j用空格隔开,询问第i号元素到第j号元素之间的最小值

输出

每个询问输出一行,包含一个整数,为询问区间内的最小值

样例输入

5
1 2 3 4 5
2
1 5
3 4

样例输出

1
3

题目来源

NUAA




#include<iostream>
#include<cmath>
using namespace std;

int main(){
	int N,p,q,i,j,M;
	int Q;
	int *a;
	int **dp;
	//cin>>N;
	scanf("%d",&N);
	a = new int[N];
	for(i=0; i<N; i++){
		//cin>>a[i];
		scanf("%d",&a[i]);
	}
	M = (int)ceil( log((float)N) / log((float)2) );
	dp = new int*[N];
	for(i=0; i<N; i++){
		dp[i] = new int[M];
	}
	for(i=0; i<N; i++){
		dp[i][0] = a[i];
	}
	for(j=1; j<M; j++){
		for(i=0; i+pow((float)2,j)-1<N; i++){			//注意i的范围
			dp[i][j] = min( dp[i][j-1], dp[i+(int)pow( (float)2, j-1 ) ][j-1] );
		}
	}
	cin>>Q;
	while(Q--){
		//cin>>p>>q;
		scanf("%d %d",&p,&q);
		p--;
		q--;
		j = (int)( log( float(q-p+1) ) / log( float(2) ) );
		//cout<<min(dp[p][j], dp[ q-(int)pow( (float)2, j ) +1 ][j])<<endl;
		printf("%d\n",min(dp[p][j], dp[ q-(int)pow( (float)2, j ) +1 ][j]));
	}

	for(i=0; i<N; i++){
		delete[] dp[i];
	}
	delete[] dp;
	delete[] a;
}





你可能感兴趣的:(ACM,区间最值,南邮OJ)