【题目描述】
John有n头奶牛(1 ≤ n ≤ 50000),给定Q个询问区间(1 ≤ Q ≤ 200000)和每头奶牛的高度(1 ≤ 高度 ≤ 1000000),对于每个询问区间,询问在此区间内最高牛和最矮牛的高度差。
【输入描述】
第一行输入两个整数n、Q;
接下来n行,每行输入一个整数,表示每头牛的高度;
接下来Q行,每行输入两个整数L、R(1 ≤ L ≤ R ≤ n),表示询问区间。
【输出描述】
输出Q行,每行包含一个整数,表示在此区间内最高牛和最矮牛的高度差。
【输入样例】
6 3
1
7
3
4
2
5
1 5
4 6
2 2
【输出样例】
6
3
0
源代码: #include<cstdio> #include<cmath> int m,n,k,i[50001],f1[50001][16],f2[50001][16]; int main() //稀疏表(ST表)。 { scanf("%d%d",&n,&m); for (int a=1;a<=n;a++) { scanf("%d",&i[a]); f1[a][0]=f2[a][0]=i[a]; } //根据f[i][i]初始化初值。 k=floor(log((double)n)/log(2.0)); for (int a=1;a<=k;a++) //DP预处理,f[i,j]表示从第 i 点开始 2^j 个点的最值,表示区间 [i,i+(2^j)-1],则有 [i,j]=[i,j-1]∪[i+2^(j-1),j-1]。 for (int b=1;b+(1<<(a-1))<=n;b++) //防止越界。 { f1[b][a]=f1[b][a-1]<f1[b+(1<<(a-1))][a-1]?f1[b][a-1]:f1[b+(1<<(a-1))][a-1]; //最小值。 f2[b][a]=f2[b][a-1]>f2[b+(1<<(a-1))][a-1]?f2[b][a-1]:f2[b+(1<<(a-1))][a-1]; //最大值。 } n=m; for (int a=1;a<=n;a++) //询问区间最值之差。 { int t1,t2,s1,s2; scanf("%d%d",&t1,&t2); k=floor(log((double)(t2-t1+1))/log(2.0)); //同理进行查询。 s1=f1[t1][k]<f1[t2-(1<<k)+1][k]?f1[t1][k]:f1[t2-(1<<k)+1][k]; s2=f2[t1][k]>f2[t2-(1<<k)+1][k]?f2[t1][k]:f2[t2-(1<<k)+1][k]; printf("%d ",s2-s1); } return 0; }