题目描述
给出一大串数字(编号为1到N),给定M个询问,每次询问两个数字A,B,要求A到B这段区间内的最大数。
输入输出格式
输入格式:
一个整数N表示数字的个数,接下来一行为N个数。第三行读入一个M,接下来M行,每行都有两个整数A,B。
输出格式:
输出共M行,每行输出一个数。
输入输出样例
输入样例#1:
6 34 1 8 123 3 2 4 1 2 1 5 3 4 2 3
输出样例#1:
34 123 123 8
说明
对于30%的数据,1<=N<=10000,1<=M<=100
对于100%的数据,1<=N<=200000,1<=M<=10000.
sparse table
f[i][j]表示从i向前走2^j步之间的最小值
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> int a[400000],f[400000][30]; int n,m; int max(int a,int b){ if(a>b) return a; return b; } void init(){ for(int i=1;i<=n;++i) f[i][0]=a[i]; for(int j=1;j<=30;++j) for(int i=(1<<j);i<=n;++i) f[i][j]=max(f[i][j-1],f[i-(1<<(j-1))][j-1]);//预处理,RMQ } int query(int l,int r){ int x=log(r-l+1)/log(2); return max(f[r][x],f[l+(1<<x)-1][x]);//将区间分成两二进制数段 } int main(){ scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]); init(); scanf("%d",&m); for(int i=1;i<=m;++i){ int l,r; scanf("%d %d",&l,&r); printf("%d ",query(l,r)); } return 0; }