• 【基础算法-ST表】入门 -C++


    前言

    学了树状数组看到ST表模板跃跃欲试的时候发现完全没思路,因为给出的查询的时间实在太短了!几乎是需要完成O(1)查询。所以ST表到底是什么神仙算法能够做到这么快的查询?

    ST表

    ST表是一个用来解决RMQ问题(区间最值问题)的有效算法。
    它的功能也很简单。
    O(nlogn)预处理,O(1)查询区间最值。
    其他好像真还没什么用了

    算法

    ST表利用的是倍增的思路来实现的。
    怎么说呢,ST表确实很神奇。
    拿最大值来说吧...
    我们用f[i][j]表示第i个数开始的(2^j)个数中的最大值。
    p.s. 下面的图是这个大佬画的
    转移的时候我们可以把当前区间拆成两个区间并分别取最大值(注意这里的编号是从1开始的)

    查询也比较简单;
    首先要计算(log_2)(区间长度)
    然后分别查询左右段店,保证覆盖整个区间。
    在这里插入图片描述
    p.s因为我们需要找到一个点x使得(x+2^k-1=r),然后移项就可以得到(x=r-2^k+1),所以把x作为从右端点查询的区间的左端点,也就是(r-2^k+1)

    代码

    代码就比较好理解了...

    #include<bits/stdc++.h>
    using namespace std;
    inline int read()
    {
       int x=0,f=1;
       char ch=getchar();
       while(ch<'0'||ch>'9'){
           if(ch=='-')
               f=-1;
           ch=getchar();
       }
       while(ch>='0'&&ch<='9'){
           x=(x<<1)+(x<<3)+(ch^48);
           ch=getchar();
       }
       return x*f;
    }
    
    int f[100001][40],b,n,m,p,l,r;
    int main()
    {
        n=read(),m=read();
        for(int i=1;i<=n;i++)
        	f[i][0]=read();
        b=(int)(log(n)/log(2));
        for(int j=1;j<=b;j++)
            for(int i=1;i<=n-(1<<j)+1;i++)
                f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
        for(int i=1;i<=m;i++) 
        {
            l=read(),r=read();
            p=(int)(log(r-l+1)/log(2));
            printf("%d
    ",max(f[l][p],f[r-(1<<p)+1][p]));
        }
        return 0;
    } 
    

    ov.

    个人博客地址: www.moyujiang.com 或 moyujiang.top
  • 相关阅读:
    rabbitMq交换机direct、topics
    rabbitMq及安装、fanout交换机-分发(发布/订阅)
    rabbitmq
    .sh文件启动 jenkins
    雪花算法、二进制运算
    收银台数据库存储AES加解密
    数据库事物
    excel技巧
    日期计算、正则、sequence、索引、表连接、mybatis
    oracle常用函数介绍
  • 原文地址:https://www.cnblogs.com/moyujiang/p/11226303.html
Copyright © 2020-2023  润新知