• ST表实现RMQ


    ST表实现RMQ

    什么是RMQ?
    RMQ 是英文 Range Maximum/Minimum Query 的缩写,表示区间最大(最小)值。

    什么是ST表?
    ST 表是用于解决 可重复贡献问题 的数据结构。
    除 RMQ 以外,还有其它的“可重复贡献问题”。例如“区间按位和”、“区间按位或”、“区间 GCD”,ST 表都能高效地解决
    (都是可以重复贡献问题)

    对于更好的解释:OI-wiki_ST表

    用ST表实现RMQ问题?
    时间复杂度:(O(nlog n)-O(1))
    空间复杂度:(O(nlog n))

    『题目传送门』:洛谷P3865 ST表
    题目大意:给定 (n) 个数,有 (m) 个询问,对于每个询问,你需要回答区间 ([l,r]) 中的最大值。

    关键思想:
    令一个数组(f(i,j))表示区间([i,i+2^{j}-1])的最大值,那么显然就有(f(i,0) = a_i)
    预处理数组关键递推式:
    (f(i,j) =max( f(i,j-1),f(i+2^{j-1},j-1)))
    查询操作:
    查询:对于每个询问 ([l,r]) ,把它分成两部分: (f[l,l+2^s-1])(f[r-2^s+1,r]) 。其中 (s=leftlfloorlog_2(r-l+1) ight floor)

    代码实现

    //#define judge
    // Author: oceanlvr
    #include <bits/stdc++.h>
    using namespace std;
    static int faster_iostream = []() {
      std::ios::sync_with_stdio(false);
      std::cin.tie(NULL);
      return 0;
    }();
    const int logn = 21;
    const int maxn = 1e6 + 10;
    //令go(i,j)表示区间[i,i+2^j-1]的最大值。
    int go[maxn][logn], Logn[maxn];
    void pre() {
      Logn[1] = 0;
      Logn[2] = 1;
      for (int i = 3; i < maxn; i++) Logn[i] = Logn[i / 2] + 1;
    }
    
    int n, m;
    int l, r;
    int main() {
      cin >> n >> m;
      for (int i = 1; i <= n; i++) cin >> go[i][0];
      pre();  //预处理Log
      for (int j = 1; j <= logn; j++) {
        for (int i = 1; i + (1 << j) - 1 <= n; i++) {
          /*
            预处理区间
            把区间分为[i,j]分为[i,i+2^{j-1}-1] [i+2^{j-1},i+2^{j}-1]
            1.即从i开始,向后跳2^{j-1}个点,右区间到i+2^{j-1}-1
            2.即从i+2^{j-1}开始,向后跳2^{j-1}个点,右区间到i+2^{j}-1
          */
          go[i][j] = max(go[i][j - 1], go[i + (1 << (j - 1))][j - 1]);
        }
      }
      for (int i = 1; i <= m; i++) {
        int x, y;
        cin >> x >> y;
        int s = Logn[y - x + 1];
        /*
          go(i,j)表示区间[i,i+2^j-1]的最大值。
          那么对于一对查询x,y,求[x,y]区间内的最大值
          对于区间长度(y - x + 1):
          有 [log(y - x + 1)]_{floor} = s
          [x][s]和[y - (1 << s) + 1][s]
        */
        cout << max(go[x][s], go[y - (1 << s) + 1][s]) << endl;
      }
      return 0;
    }
    
    
  • 相关阅读:
    Dask教程
    python程序—利用socket监控端口
    python程序—封装案例
    python程序—士兵出击
    Python三大神器:装饰器,迭代器,生成器
    python程序—名片管理系统
    python程序—系统检测
    python程序—用户登录
    (七)javac编译
    Unity系统消息广播
  • 原文地址:https://www.cnblogs.com/adameta/p/12470003.html
Copyright © 2020-2023  润新知