O(1) 查询某小块的问题

https://leetcode.cn/problems/sliding-window-maximum/description/

这个题用优先队列就慢了,每次调整要logn,总的nlogn

要想O(n)需要预处理
有两种预处理方法

ST 稀疏表

  1. RMQ:Range Minimum Query
  2. 区间最大最小值问题
  3. RGQ: Range GCD Query
  4. 区间最大公约数问题

O(1) 查询某小块的问题_第1张图片

怎么用

查询红色区间,要将它分成两个等长的绿色区间(允许重叠但不能超过了)
绿条的长度是 2 m 2^m 2m,其中 2 m < = 查询区间长度 2^m<=查询区间长度 2m<=查询区间长度

初始化

需要把所有的 2 i 2^i 2i区间的值都算出来先

例:{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

  1. [1], [2], [3], [4], [5], [6], [7], [8], [9], [10] // 2^0
  2. [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10] // 2^1
  3. [1, 4], [2, 5], [3, 6], [4, 7], [5, 8], [6, 9], [7, 10] // 2^2
  4. [1, 8], [2, 9], [3, 10] // 2^3

在这个阶段,每层都能用到上一层的,比方说[1, 8]=[1, 4]+[5, 8]
[i, i+ 2 p o w e r 2^{power} 2power] = [i, i+ 2 p o w e r − 1 2^{power-1} 2power1] + [ i+ 2 p o w e r − 1 2^{power-1} 2power1, (i+ 2 p o w e r − 1 2^{power-1} 2power1)+ 2 p o w e r − 1 2^{power-1} 2power1]

细节

log(n)

int log(x){
	if(!x) return 0;
	return 1+log(x/2);
}

更快的递推打表:

  Logn[1] = 0;
  Logn[2] = 1;
  for (int i = 3; i < maxn; i++) {
    Logn[i] = Logn[i / 2] + 1;
  }

2 x 2^x 2x幂求法

1<

ST存储

A[log(n)][n]

建表模板

  for (int power = 1; power <= logn; power++)
    for (int i = 1; i + (1 << power) - 1 <= n; i++){
      f[power][i] = max(f[power - 1][i], f[power - 1][i + (1 << (power - 1))]);

线段树

ST表用在这题是没问题的,但是如果换个题,里面元素会改,就很麻烦,这种情况用线段树比较好

初始化

  1. [1, 10]
  2. [1, 5], [6, 10]
  3. [1, 3], [4, 5], [6, 8], [9, 10]
  4. [1, 2], [3], [4], [5], [6, 7], [8], [9], [10]
  5. [1], [2], [3], [4], [5], [6], [7], [8], [9], [10]

怎么用

查询[2, 7]
[1, 10]
[1, 5] + [6, 10]
[1, 3] + [4, 5] + [6, 8] [9, 10]
[1, 2], [3], [4, 5], [6, 7], [8]
[1], [2], [3], [4, 5], [6, 7]

用若干个大小为 2 x 2^x 2x的块拼成查询区间

// [ql, qr] 为查询区间
int ql, qr;
// [s, t] 为当前节点包含的区间, p 为当前节点的编号
int getsum(int s, int t, int p) {
  if (l <= s && t <= r)  return d[p];  

  int m = s + ((t - s) >> 1), sum = 0;
  if (ql <= m) sum += getsum(s, m, p * 2);
  if (qr > m) sum += getsum(m + 1, t, p * 2 + 1);
  
  return sum;
}

ans=getsum(1, N, 1);

更新之类的,下次做到对应的题再研究吧,什么懒标记的

你可能感兴趣的:(算法,算法,RMQ,ST表,线段树)