首页 > 其他分享 >RMQ 问题的两种实现办法(线段树查询和稀疏表(Sparse Table表)查询)

RMQ 问题的两种实现办法(线段树查询和稀疏表(Sparse Table表)查询)

时间:2023-05-26 15:05:42浏览次数:77  
标签:RMQ int 线段 mid 查询 Sparse Query


引言

RMQ算法(Range Minimum/Maximum Query) 是静态区间极值查询的高效算法,在各种算法竞赛中常常出现,虽然不会单独拿出来做一个题,但是经常作为题的一部分。依据所需实现的不同性能可以有多种写法,这里主要讲基于线段树和稀疏表(Sparse Table)的两种方法。

线段树实现RMQ

线段树是维护区间的一类高效数据结构,依据这个特性,我们可以用线段树实现RMQ算法,用线段树实现的RMQ算法不仅可以查询区间最小值,还可以更改某个节点的值。

时间复杂度:预处理时O(nlogn),单次询问O(longn)

void Build(int p,int l,int r)
{
    if(l == r)
    {
        tree[p] = x[l];
        return;
    }
    int mid = (l + r) / 2;
    Build(p * 2,l,mid);
    Build(p * 2 + 1,mid + 1,r);
    tree[p] = min(tree[p * 2],tree[p * 2 + 1]);
}
int Query(int p,int l,int r,int x,int y)
{
    /*在plr这棵子树里查询x到y区间的最小值*/
    if(x <= l && r <= y)
        return tree[p];
    int mid = (l + r) / 2;
    if(y <= mid)
        return Query(p * 2,l,mid,x,y);
    if(x > mid)
        return Query(p * 2 + 1,mid + 1,r,x,y);
    return min(Query(p * 2,l,mid,x,mid),Query(p * 2 + 1,mid + 1,r,mid + 1,y));
}

ST表实现RMQ

线段树的查询复杂度为O(log n),对于有多组询问的题还是太慢,有了线段树实现的铺垫,我们思考,是否有一种方法能预先处理出区间极值呢,答案是有的,就是ST表。

时间复杂度:预处理时O(nlogn),单次询问O(1)

预处理的时候用到一种dp的思想。

d[i][j]代表这样一段区间的最值:左端点为i,长度为2^j,也就意味着它管辖了[i,i + 2 ^(j - 1)]。

void st_init(int n)
{
    for(int i = 1;i <= n; i++)
        d[i][0] = x[i];
    for(int j = 1;(1 << j) <= n; j++)
        for(int i = 1;i + (1 << j) - 1 <= n; i++)
            d[i][j] = min(d[i][j - 1],d[i + (1 << (j - 1))][j - 1]);
    for(int i = 1;i <= n; i++)
    {
        int k = 0;
        while((1 << (k + 1)) <= i)
            k++;
        mn[i] = k;
    }
}
int STquery(int l,int r)
{
    int k = mn[r - l + 1];
    return min(d[l][k],d[r - (1 << k) + 1][k]);
}

 

标签:RMQ,int,线段,mid,查询,Sparse,Query
From: https://blog.51cto.com/u_16131191/6356109

相关文章

  • Excel数据查询之INDEX和MATCH函数
    INDEX函数的作用INDEX(单元格区域,指定的行数,指定的列数)INDEX函数用于在一个区域中,根据指定的行、列号来返回内容=INDEX(A1:D4,3,4)  返回A1:D4单元格区域第3行和第4列交叉处的单元格,即D3单元格 MATCH函数的作用     MATCH函数用于在一行或一列的......
  • Kafka实时数据即席查询应用与实践
    作者:vivo互联网搜索团队-DengJieKafka中的实时数据是以Topic的概念进行分类存储,而Topic的数据是有一定时效性的,比如保存24小时、36小时、48小时等。而在定位一些实时数据的Case时,如果没有对实时数据进行历史归档,在排查问题时,没有日志追述,会很难定位是哪个环节的问题。一、背景Ka......
  • Kafka实时数据即席查询应用与实践
    作者:vivo互联网搜索团队-DengJie Kafka中的实时数据是以Topic的概念进行分类存储,而Topic的数据是有一定时效性的,比如保存24小时、36小时、48小时等。而在定位一些实时数据的Case时,如果没有对实时数据进行历史归档,在排查问题时,没有日志追述,会很难定位是哪个环节的问题。一......
  • 分页查询设置每页多少条数据
    intpageIndex=request.getParameter("pageIndex")==null?1:Integer.parseInt(request.getParameter("pageIndex"));intpageSize=request.getParameter("pageSize")==null?15:Integer.parseInt(request.getParameter("p......
  • 5)基本查询语句
    1、select语句:select格式:select字段列表from数据源[where条件表达式][groupby分组字段[having条件表达式]][orderby排序字段[asc|desc]]where字句用于指定记录的过滤条件,groupby子句用于对检索的数据进行分组;having子句对分组后的数据进行筛选;orderby子句......
  • F查询与Q查询
    F查询与Q查询1、aggregate若想把整张表当成一个组来使用聚合函数,应该调用aggregate#1、先导入聚合函数fromdjango.db.modelsimportMax,Min,Avg,Sum,Count"""小窍门:只要是跟数据库相关的模块基本都在django.db.models里面如果没有那么应该在django.db里"""#2......
  • ORACLE表空间使用量查询SQL
    SELECTUpper(F.TABLESPACE_NAME)AS表空间名,round(D.TOT_GROOTTE_MB/1024,2)AS"总大小(G)",round((D.TOT_GROOTTE_MB-F.TOTAL_BYTES)/1024,2)AS"已使用空间(G)",round(F.TOTAL_BYTES/1024,2)AS"空闲空间(G)",R......
  • 星座运势查询接口
    接入点说明:十二星座为:白羊座、金牛座、双子座、巨蟹座、狮子座、处女座、天秤座、天蝎座、射手座、摩羯座、水瓶座、双鱼座。接口地址:https://route.showapi.com/872-1?showapi_appid=&showapi_sign=  查看密匙返回格式:json  纯java:publicstaticvoidm......
  • Elasticsearch 之 join 关联查询及使用场景
    在Elasticsearch这样的分布式系统中执行类似SQL的join连接是代价是比较大的,然而,Elasticsearch却给我们提供了基于水平扩展的两种连接形式。这句话摘自Elasticsearch官网,从“然而”来看,说明某些场景某些情况下我们还是可以使用的一、join总述1、关系类比在关系型数据库中,以MySQ......
  • 报错问题:谷粒商城关于pubsub、publish报错,无法发送查询品牌信息的请求
    1、npminstall--savepubsub-js2、在src下的main.js中引用:①importPubSubfrom'pubsub-js'②Vue.prototype.PubSub=PubSub ......