題目背景
這是一道ST表經典題——靜態區間最大值
請注意最大數據時限只有0.8s,數據強度不低,請務必保證你的每次查詢復雜度為 O(1)
題目描述
給定一個長度為 N 的數列,和 M 次詢問,求出每一次詢問的區間內數字的最大值。
輸入輸出格式
輸入格式:
第一行包含兩個整數 N,M ,分別表示數列的長度和詢問的個數。
第二行包含 N 個整數(記為 a_i),依次表示數列的第 i項。
接下來 M行,每行包含兩個整數 l_i, r_i,表示查詢的區間為 [ l_i, r_i]
輸出格式:
輸出包含 M行,每行一個整數,依次表示每一次詢問的結果。
輸入輸出樣例
說明
對於30%的數據,滿足:1≤N,M≤10
對於70%的數據,滿足: 11≤N,M≤10^5
對於100%的數據,滿足:1≤N≤10^5,1≤M≤10^6,ai∈[0,10^9],1≤li≤ri≤N
分析:
所謂的ST表就是一種類似於線段樹的數據結構,然后通過類似倍增的查找進行求解區間最值。
CODE:
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 int n,m,a[100005],maxn[100005][25]; 8 int max(int x,int y){return x>y?x:y;} 9 int read(){ 10 char c=getchar();int ans=0; 11 while (c<'0'||c>'9') c=getchar(); 12 while (c>='0'&&c<='9') ans=(ans<<1)+(ans<<3)+(c^48),c=getchar(); 13 return ans; 14 } 15 int main(){ 16 n=read(),m=read(); 17 for (int i=1;i<=n;i++) a[i]=read(),maxn[i][0]=a[i]; 18 for (int l=1;(1<<l)<=n;l++) 19 for (int i=1;i+(1<<l)-1<=n;i++) 20 maxn[i][l]=max(maxn[i][l-1],maxn[i+(1<<(l-1))][l-1]); 21 for (int i=1,x,y;i<=m;i++){ 22 x=read(),y=read(); 23 int l=(int)log2(y-x+1); 24 printf("%d\n",max(maxn[x][l],maxn[y-(1<<l)+1][l])); 25 } 26 return 0; 27 }