算法详解——st表

st表是解决区间RMQ(区间最值问题)的一类算法,时间复杂度为O(nlogn)的预处理和O(1)的查询,其主要运用了类似倍增的思想...

总体来说,st表的用处还是挺大的,代码也比较短,容易记...



st表

若现在给定一个长度为n的序列A,每次给定两个数l,r,求出A[l]~A[r]中的最大值...

那么我们考虑怎么做,首先是朴素做法,每次询问最大值时用for循环从l到r跑一遍,每次循环复杂度为O(r - l)

那有没有一种算法可以让我们以O(1)的复杂度就知道最大值呢?

这时我们引进st表算法...

具体做法:

我们定义一个二维数组st[i][j]表示区间[i,i+2^j-1]里的最大值,那么有st[i][0] = A[i],即A[i]是区间[i,i]的最大值,然后我们运用倍增的思想,每次维护区间最值就行了,预处理的代码如下:

inline void init()
{
    for(int i = 1;i <= n;i ++) st[i][0] = a[i];
    for(int j = 1;j <= 21;j ++)
        for(int i = 1;(i + (1<<j) - 1) <= n;i ++)
            st[i][j] = max(st[i][j - 1],st[i + 1<<(j - 1)][j - 1]);
}

关于查询,我们需要先对查询区间的长度取一个对数k,那么2^k一定大于等于区间长度的一半,接着我们从左右两个端点处向内取最大值(即使有重叠也没事),这样我们就O(1)的查询出了区间的最大值,代码如下:

inline int query(int l,int r)
{
    int k = log(r - l + 1);
    return max(st[l][k],st[r - (1<<k) + 1][k]);
} 

下面有一道板子题

洛谷P3865

代码如下:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

const int maxn = 1e5 + 5;
int n,m;
int st[maxn][23];

inline int read()
{
  char ch = getchar();int x = 0,f = 1;
  while(ch<‘0‘||ch>‘9‘){if(ch == ‘-‘) f = -1; ch = getchar();}
  while(ch>=‘0‘&&ch<=‘9‘){x = x*10 + ch -‘0‘; ch = getchar();}
  return x*f;
}

inline void init()
{
  for(int i = 1;i <= 21;i ++)
    for(int j = 1;j+(1<<i)-1 <= n;j ++)
      st[j][i] = std::max(st[j][i-1],st[j+(1<<(i-1))][i-1]);
}

inline int query(int l,int r)
{
  int k = log2(r-l+1);
  return std::max(st[l][k],st[r-(1<<len)+1][k]);
}

int main(int argc, char const *argv[])
{
  n = read();
  m = read();
  for(int i = 1;i <= n;i ++) st[i][0] = read();
  init();
  for(int i = 1;i <= m;i ++)
  {
    int l = read();
    int r = read();
    printf("%d\n",query(l,r));
  }
  return 0;
}

原文地址:https://www.cnblogs.com/Ackers/p/10010223.html

时间: 2024-10-03 20:14:01

算法详解——st表的相关文章

ST算法详解

ST算法详解 Coded by Jelly_Goat. All rights reserved. 这个主要是说ST表的. 首先了解一下ST表是什么. 先来一个老套的情景带入. (假设所有的题目都是1s,128ms) 有一天,蒟蒻Jelly_Goat用手(?) 给你出了一套\(n<=1000\)的数据,然后让你输出\(m<=1000\)次最小值. 你说了,那不就直接暴力吗? 然后,蒟蒻Jelly不服,又开始用C++出了\(n<=10000\),\(m<=10000\)的数据. 你可能

KMP算法详解(图示+代码)

算法过程非常绕,不要企图一次就能看明白,多尝试就会明白一些.下面试图用比较直观的方法解释这个算法,对KMP算法的解释如下: 1. 首先,字符串"BBC ABCDAB ABCDABCDABDE"的第一个字符与搜索词"ABCDABD"的第一个字符,进行比较.因为B与A不匹配,所以搜索词后移一位. 2. 因为B与A不匹配,搜索词再往后移. 3. 就这样,直到字符串有一个字符,与搜索词的第一个字符相同为止. 4. 接着比较字符串和搜索词的下一个字符,还是相同. 5. 直到字

php 二分查找法算法详解

一.概念:二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功. 二.代

【转】AC算法详解

原文转自:http://blog.csdn.net/joylnwang/article/details/6793192 AC算法是Alfred V.Aho(<编译原理>(龙书)的作者),和Margaret J.Corasick于1974年提出(与KMP算法同年)的一个经典的多模式匹配算法,可以保证对于给定的长度为n的文本,和模式集合P{p1,p2,...pm},在O(n)时间复杂度内,找到文本中的所有目标模式,而与模式集合的规模m无关.正如KMP算法在单模式匹配方面的突出贡献一样,AC算法对于

支持向量机(SVM)(五)-- SMO算法详解

一.我们先回顾下SVM问题. A.线性可分问题 1.SVM基本原理: SVM使用一种非线性映射,把原训练            数据映射到较高的维.在新的维上,搜索最佳分离超平面,两个类的数据总可以被超平面分开. 2.问题的提出: 3.如何选取最优的划分直线f(x)呢? 4.求解:凸二次规划 建立拉格朗日函数: 求偏导数: B.线性不可分问题 1.核函数 如下图:横轴上端点a和b之间红色部分里的所有点定为正类,两边的黑色部分里的点定为负类. 设: g(x)转化为f(y)=<a,y> g(x)=

Manacher算法详解

[转] Manacher算法详解 转载自: http://blog.csdn.net/dyx404514/article/details/42061017 Manacher算法 算法总结第三弹 manacher算法,前面讲了两个字符串相算法——kmp和拓展kmp,这次来还是来总结一个字符串算法,manacher算法,我习惯叫他 “马拉车”算法. 相对于前面介绍的两个算法,Manacher算法的应用范围要狭窄得多,但是它的思想和拓展kmp算法有很多共通支出,所以在这里介绍一下.Manacher算法

Tarjan算法详解

Tarjan算法详解 [概念] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. [功能] Tarjan算法的用途之一是,求一个有向图G=(V,E)里极大强连

安全体系(一)—— DES算法详解

本文主要介绍了DES算法的步骤,包括IP置换.密钥置换.E扩展置换.S盒代替.P盒置换和末置换. 安全体系(零)-- 加解密算法.消息摘要.消息认证技术.数字签名与公钥证书 安全体系(二)--RSA算法详解 安全体系(三)--SHA1算法详解 1.DES算法简介 DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准. DES是一个分组加密算法,典型的DES以64位为分组对数据加密,加密和解密用的是同一个算法. 密钥长64位,密钥事实上是56位参与DES运算(第8.16.24.32.40

机器学习经典算法详解及Python实现--CART分类决策树、回归树和模型树

摘要: Classification And Regression Tree(CART)是一种很重要的机器学习算法,既可以用于创建分类树(Classification Tree),也可以用于创建回归树(Regression Tree),本文介绍了CART用于离散标签分类决策和连续特征回归时的原理.决策树创建过程分析了信息混乱度度量Gini指数.连续和离散特征的特殊处理.连续和离散特征共存时函数的特殊处理和后剪枝:用于回归时则介绍了回归树和模型树的原理.适用场景和创建过程.个人认为,回归树和模型树