有n个数,【l,r】 找max,m次询问
9,3,1,7,5,6,0,8
【0,5】9? ?,【4,5】6? ?,【3,5】7
看上去比较简单,是因为人脑进行了扫描。
以下代码是不完整的,欢迎大家进行修正。
import java.util.Scanner;
public class ST表 {
public static void main(String[] args) {
int[] arr = {9, 3, 1, 7, 5, 6, 0, 8};
int ans = 0, l = 0, r = 7;
System.out.println("请输入下标范围:");
Scanner sc = new Scanner(System.in);
int s1 = sc.nextInt();
int s2 = sc.nextInt();
while (s1 <= s2) {
for (int i = s1; i <= s2; i++) {
if (arr[i] > arr[i + 1]) { // 注意:这里我改成了arr[i] > arr[i + 1],以找到最大的两个连续元素之和
}
}
s1++;
}
System.out.println(ans);
}
}
缺点:当m特别大的时候,会炸掉----》优化
一个大区间若能被两个小区间覆盖,那么大区间的最值等于两个小区间的最值
两个小区间有部分重合,重合不影响结果。
(1)把整个数列分为很多小区间,并提前计算出每个小区间的最值
(2)对任意一个区间最值查询,找到覆盖它的两个小区间,用小区间的最值算出答案
第1组:长度为1的小区间,有n个小区间,每个小区间有1个元素
第2组:长度为2的小区间,有n个小区间,每个小区间有2个元素
第3组:长度为4的小区间,有n个小区间,每个小区间有4个元素
.........
共有logn组
(1)以任意元素为起点,有长度为1,2,4,....的小区间
(2)以任意元素为终点,它前面也有长度为1,2,4,...的小区间
以L为起点的小区间
以R为终点的小区间
这两个西秋季首尾相接覆盖[L,R]
一次查询的计算复杂度是O(1)
(1)静态数组的查询
(2)极大的查询次数,每次查询只需要O(1)
(3)核心思想:“大区间被两个小区间覆盖,小区间的重复覆盖不影响结果”