<题目链接>
题目大意:
给你一段序列,进行q次区间查询,每次都输出询问区间内的最小值。
解题分析:
RMQ模板题,下面用在线算法——ST算法求解。不懂ST算法的可以看这篇博客 >>>
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 using namespace std; 6 const int MAXN =2e5+10; 7 int maxsum[MAXN][20],minsum[MAXN][20]; //表示从第i个数起连续2^j个数中的最大值/最小值 8 void RMQ(int num){ //预处理maxsum、minsum数组 9 for(int j=1;j<20;j++){ 10 for(int i=1;i<=num;i++){ 11 if(i+(1<<j)-1<=num){ 12 maxsum[i][j]=max(maxsum[i][j-1],maxsum[i+(1<<(j-1))][j-1]); 13 minsum[i][j]=min(minsum[i][j-1],minsum[i+(1<<(j-1))][j-1]); 14 } 15 } 16 } 17 } 18 int main(){ 19 int T,ncase=0,num,q; 20 scanf("%d",&T); 21 while(T--){ 22 scanf("%d%d",&num,&q); 23 for(int i=1;i<=num;i++){ 24 scanf("%d",&maxsum[i][0]); 25 minsum[i][0]=maxsum[i][0]; //初始化 26 } 27 RMQ(num); 28 printf("Scenario #%d:\n",++ncase); 29 while(q--){ 30 int st,en,maxl,minl; 31 scanf("%d%d",&st,&en); 32 int k=(int)((log(en-st+1))/log(2.0)); 33 maxl=max(maxsum[st][k],maxsum[en-(1<<k)+1][k]); 34 minl=min(minsum[st][k],minsum[en-(1<<k)+1][k]); 35 printf("%d\n",minl); 36 } 37 } 38 return 0; 39 }
2018-10-19