区间最值
时间限制(普通/Java) :
1000 MS/ 3000 MS 运行内存限制 : 65536 KByte
总提交 : 1034 测试通过 : 241
总提交 : 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;
}