题目背景
这是一道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 ",max(maxn[x][l],maxn[y-(1<<l)+1][l])); 25 } 26 return 0; 27 }