首页 > 编程语言 >算法笔记——ST表

算法笔记——ST表

时间:2023-08-02 16:35:02浏览次数:32  
标签:log2 cout int 笔记 ST 算法 区间 长度

ST表

ST表是一种简单的数据结构,主要用于解决RMQ问题(区间最大/最小值问题)主要应用倍增的思想,可以实现O(nlogn)预处理,O(1)查询

1.预处理ST表

倍增法递推:用两个等长的小区间拼凑一个大区间
f[i][j]表示以第i个数为起点,长度为2^j的区间里的最大值/最小值
f[i][j]=max(f[i][j-1],f[i+2^j-1][j-1])
区间终点:i+2^j-1 <= n

代码实现

for(int i=1;i<=n;i++)
    cin>>f[i][0];
for(int j=1;j<=20;j++)//先枚举区间长度的指数
{
    for(int i=1;i+(1<<j)-1<=n;i++)//枚举起点  i+(1<<j)-1是区间的终点要受到上界n的限制
    {
        f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);//在这段代码中所举的例子是最大值,改成min(,)就是最小值,改成gcd()就是最大公约数。。类似
    }
}

对于此算法外层时间复杂度是O(logn),内层是O(n)的,总的时间复杂度就是O(nlogn)的

比如 n=6;

f[i][0]: f[1][1] f[2][2] f[3][3] f[4][4] f[5][5] f[6][6]
f[i][1]: f[1][2] f[2][3] f[3][4] f[4][5] f[5][6] 
f[i][2]: f[1][4] f[2][5] f[3][6]
if j==3:i+2^j-1=1+8-1= 8 > 6

2.处理询问

对查询区间 [l,r]做分割,拼凑,
区间长度的指数 k=log2(r-l+1) (注意:这一运算是下取整的)
我们列出所有的情况:

        //区间长度可能的情况
k = 0: {1}
k = 1: {2,3}
k = 2: {4,5,6,7}
k = 3: {8,9,10,...,15}

由此:2^k <= r-l+1 < 2*2^k,即 区间 [l,r]必可以用两个长度为2^k的区间来 重叠拼凑 出来!

代码实现

while(T--)
{
  int l,r;
  cin>>l>>r;
  int k=log2(r-l+1);
  cout<<max(f[l][k],f[r - (1<<k) + 1][k])<<endl;
}

3.拓展

ST表不仅能够解决 RMQ问题,更可以解决所有符合结合律且可重复贡献的信息查询都可以使用ST表高效进行。
可重复贡献:设有一个二元运算f(x,y) 满足 f(a,a) = a,则运算f是可重复贡献的,显然最大值,最小值,最大公约数,按位或,按位与都符合这个条件。
可重复贡献的意义在于,可以对两个交集不为空的区间进行信息合并。

例题:

洛谷:P2880 [USACO07JAN] Balanced Lineup G

#include<bits/stdc++.h>
using namespace std;
const int N=5e4+10;
int maxx[N][21];
int minn[N][21];//注意第二位代表的数字是j是区间长度的log因此不需要开太大

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
    int n,q;
    cin>>n>>q;
    for(int i=1;i<=n;i++)
    {
        cin>>maxx[i][0];
        minn[i][0]=maxx[i][0];
    }
    for(int j=1;j<=20;j++)
    {
        for(int i=1;i+(1<<j)-1<=n;i++)
        {
            maxx[i][j]=max(maxx[i][j-1],maxx[i+(1<<(j-1))][j-1]);
            minn[i][j]=min(minn[i][j-1],minn[i+(1<<(j-1))][j-1]);
        }
    }
    int l,r;
    while(q--)
    {
        cin>>l>>r;
        int k=log2(r-l+1);
        cout<<max(maxx[l][k],maxx[r - (1<<k) + 1][k])-min(minn[l][k],minn[r - (1<<k) + 1][k])<<endl;
    }
    return 0;
}

标签:log2,cout,int,笔记,ST,算法,区间,长度
From: https://www.cnblogs.com/OhLonesomeMe/p/17601035.html

相关文章

  • php-elasticsearch客户端基本使用
    php-elasticsearch客户端基本使用标签(空格分隔):php,elasticsearch官方文档:https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/getting-started-php.html#_searching_documents官方中文文档(已过时):https://www.elastic.co/guide/cn/elasticsearch/php/cur......
  • [刷题笔记] Luogu P1466 [USACO2.2] 集合 Subset Sums
    ProblemDescription有一个长度为\(n\)的数组为\(1-n\),求有多少种选择方案使得选择数之和等于序列和的一半Solution题面翻译成这样是不是就好做了?首先,序列和的一半我们可以计算出\(n\times(n+1)\div2\div2\),显然序列和的一半只有是整数才有解,如果不是整数直接输出0即可。......
  • 浅谈Map<String, String[]> p=req.getParameterMap();
    这行代码用于获取当前HTTP请求中的所有参数,并将它们存储在一个Map<String,String[]>类型的对象中。解释如下:req:这是一个HttpServletRequest对象,表示当前的HTTP请求。通过它可以获取请求中的参数信息。getParameterMap():这是HttpServletRequest接口的方法,用......
  • 「延期通知」LiveVideoStackCon 2022 音视频技术大会北京站
    亲爱的LiveVideoStack伙伴们:感谢大家一直以来对LiveVideoStackCon2022音视频技术大会北京站活动的关注与支持。根据近期多方沟通结果,受到目前各地疫情情况及进京防控政策影响,为保证大会各方参与人员的参会体验,本次活动将延期至2022年11月25日-26日举办,给您带来的不便我们深表歉......
  • LiveVideoStack公众号2021年终盘点
    在2021年伊始,我们翻译过TsahiLevent-Levi关于今年WebRTC流行趋势的文章,文中提到2021年将是“还债”的一年,此前所进行的系统设计、软件架构或软件开发都将迎来最终结果;同时它也将是服务及传输质量不断优化的一年。在供给侧长期大于需求侧的当下,技术迭代的速度远远甩开新需求增长的......
  • Vue学习笔记:VCA下使用provide与 inject
    在VCA模式下使用provide和inject与之前文档中VOA模式类似,不同的是需要在使用前进行importimport{provide,inject}from'vue'在此篇文档中,使用一个示例来演示provide与inject的使用功能如下:组件NavbarDetailList部署在根组件App上。在初始页面,显示Navbar与List。List组件......
  • 哪篇论文宣布了 HTAP 数据库的诞生? | StoneDB学术分享会#5
    本文是StoneDB学术分享会专栏的第五篇,我们来分享一下HTAP学术界上比较经典的一篇论文《ACommonDatabaseApproachforOLTPandOLAPUsinganIn-MemoryColumnDataBase》。<br>为什么说这篇论文经典呢,因为这篇论文来自国际著名厂商,号称欧洲最大的软件公司SAP(思爱普,截......
  • [算法题python]822.翻转卡片游戏
    在桌子上有 n 张卡片,每张卡片的正面和背面都写着一个正数(正面与背面上的数有可能不一样)。我们可以先翻转任意张卡片,然后选择其中一张卡片。如果选中的那张卡片背面的数字 x 与任意一张卡片的正面的数字都不同,那么这个数字是我们想要的数字。哪个数是这些想要的数字中最小的......
  • 为什么要做LiveVideoStack课程?
    文/包研大家好,这里是LiveVideoStack包研,很久没有用这样的方式和大家聊天了。今天的主题是,我们要推出课程产品了,希望大家多多支持。我们会上线第一门课程——《轻松掌握WebAssembly视频播放器》轻松掌握WebAssembly视频播放器,由李超老师亲自打造。如果你希望学习如何在浏览器里通......
  • [算法题python]14. 最长公共前缀
    编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。 示例1:输入:strs=["flower","flow","flight"]输出:"fl"示例2:输入:strs=["dog","racecar","car"]输出:""解释:输入不存在公共前缀。 提示:......