1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 using namespace std; 5 const int N=1e6+111; 6 int Max[N][21],Min[N][21],a[N]; 7 void ST(int *a,int n)//预处理,O(NlogN) 8 { 9 for(int i=1;i<=n;i++) 10 Min[i][0]=Max[i][0]=a[i]; 11 for(int j=1;j<=20;j++) 12 { 13 for(int i=1;i<=n;i++) 14 { 15 if(i+(1<<(j-1))<=n) 16 { 17 Max[i][j]=max(Max[i][j-1],Max[i+(1<<(j-1))][j-1]); 18 Min[i][j]=min(Min[i][j-1],Min[i+(1<<(j-1))][j-1]); 19 } 20 } 21 } 22 } 23 int Log2(int len) 24 { 25 int k=-1; 26 while(len) 27 { 28 len>>=1; 29 k++; 30 } 31 return k; 32 } 33 int main() 34 { 35 int n; 36 while(scanf("%d",&n)) 37 { 38 for(int i=1;i<=n;i++) 39 scanf("%d",&a[i]); 40 ST(a,n); 41 int l=1,r=n; 42 int k=Log2(r-l+1); 43 printf("%d %d ",max(Max[l][k],Max[r-(1<<k)+1][k]),min(Min[l][k],Min[r-(1<<k)+1][k])); 44 } 45 return 0; 46 }
概述
RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值。ST算法它可以在O(nlogn)时间内进行预处理,然后在O(1)时间内回答每个查询。