数据结构——ST表

ST表的定义

ST表,又名稀疏表,是一种基于倍增思想,用于解决可重复贡献问题的数据结构

倍增思想

这里列举一个去寻找一个区间内的最大值的例子

 

 

因为每次会将将区间增大一倍,所以才被称之为倍增思想 ,这种思想十分好用,建议友友们平常多多练习

ST表的适用范围

如果A区间和B区间可能有重叠的部分
但是并不影响A+B区间的答案,能通过 A区间答案 和 B区间答案 就加工出来
那么对应的区间询问,就是一个可重复贡献问题
例如:区间最大值,区间最小值、区间公约数等,但是区间求和就不符合这个要求
再例如:区间按位与、区间按位或,ST表都能高效地解决


ST表的优势和劣势

 RMQ问题(Range Maximum/Minimum Query)可以用ST表维护,也可以用线段树等结构维护
ST表的优势:构建过程时间复杂度0(n*logn),单次查询时间复杂度0(1),代码量较小
ST表的劣势:需要空间较大,能维护的信息非常有限,不支持修改操作

只能维护静态区间内的可重复贡献类问题,不能维护动态的

模版

预处理模版:

//st[i][j]表示的是以i为起点,长度为2^j的区间的最值
//外层循环遍历的是长度的指数,内层循环遍历的是起点 
for(int j=1;j<20;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]);}
} 

查询模版:

//maxn是统计给定区间的最值
//k是用来判断区间的长度
//l,r是给定的区间范围 
for(int i=1;i<=m;i++)
{cin>>l>>r;int k=log2(r-l+1);maxn=max(dp[l][k],dp[r-(1<<k)+1][k]);
} 

例题:

P3865 【模板】ST 表 && RMQ 问题

 

思路:十分板正的一个ST表板题,就是去求区间内的一个最大值,纯板题

#include<bits/stdc++.h>  
using namespace std;  
#define int long long  int n, m;  
int l, r;  
int st[100005][20];  signed main() {  ios::sync_with_stdio(0);  cin.tie(0);  cout.tie(0);  cin >> n >> m;  for (int i = 1; i <= n; i++) {  cin >> st[i][0];  }  for (int j = 1; j < 20; 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]);  }  }  for (int i = 1; i <= m; i++) {  cin >> l >> r;  int k = log2(r - l + 1);  cout << max(st[l][k], st[r - (1 << k) + 1][k]) << "\n";  }  return 0;  
}

 P2880 [USACO07JAN] Balanced Lineup G

 思路:也是ST表的板题,只不过是去求一遍最大值的ST表,然后再去求一遍最小值的ST表,然后减去就可以了

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,q;
int f_max[50005][17];
int f_min[50005][17];
int l,r;
signed main()
{cin>>n>>q;for(int i=1;i<=n;i++){cin>>f_max[i][0];f_min[i][0]=f_max[i][0];}for(int j=1;j<=16;j++){for(int i=1;i+(1<<j)-1<=n;i++){f_max[i][j]=max(f_max[i][j-1],f_max[i+(1<<(j-1))][j-1]);f_min[i][j]=min(f_min[i][j-1],f_min[i+(1<<(j-1))][j-1]);}}for(int i=1;i<=q;i++){cin>>l>>r;int k=log2(r-l+1);cout<<max(f_max[l][k],f_max[r-(1<<k)+1][k])-min(f_min[l][k],f_min[r-(1<<k)+1][k])<<"\n";}
}

P2251 质量检测

思路1:滑动窗口问题,可以直接单调队列解决,去寻找m区间长度的窗口内的最小值,但是和今天的主题不相符,这种写法就靠看官自己去琢磨了

思路2:ST表,这题是求区间内的最小值,但是却是给你规定了区间大小,让你找出整个区间的这么大小的最小值,直接预处理一遍,然后遍历即可,但是如果m不是2^k,就找到最大的k, 然后用m-(2^k)+1的k区间长度,去找最小值即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
int st[1000005][25]; 
signed main()
{cin>>n>>m;for(int i=1;i<=n;i++){cin>>st[i][0];}for(int j=1;j<=21;j++){for(int i=1;i+(1<<j)-1<=n;i++){st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);}}int k=log2(m);for(int i=1;i+m-1<=n;i++){cout<<min(st[i][k],st[i+m-(1<<k)][k])<<"\n";}return 0;
}

P1890 gcd区间

思路:区间gcd也是一种可重复贡献问题,因此也可以用ST表,我们直接预处理一遍,然后直接跑即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
int st[1005][15];
int l,r;
int gcd(int a,int b)
{if(b==0)return a;return gcd(b,a%b);
}
signed main()
{cin>>n>>m;for(int i=1;i<=n;i++){cin>>st[i][0];}for(int j=1;j<=14;j++){for(int i=1;i+(1<<j)-1<=n;i++){st[i][j]=gcd(st[i][j-1],st[i+(1<<(j-1))][j-1]);}}for(int i=1;i<=m;i++){cin>>l>>r;int k=log2(r-l+1);cout<<gcd(st[l][k],st[r-(1<<k)+1][k])<<"\n";}return 0;
}

P4155 [SCOI2015] 国旗计划

思路:这题其实一开始我也没看出来是ST表的题目,后来想了好久我才恍然大悟,我们首先来看题,每个士兵都有自己负责的一个区域,为L和R,然后呢,我们有m个边防站,然后我们要遍历第i个士兵必须参与的情况下,最少需要多少个哨兵

我们首先需要拆环为链,我们之间将这个数组拷贝一遍,再延伸出来一个长度,然后我们去处理士兵负责的范围,加入右区间的端点,小于左区间端点,那么我们就直接将右区间的端点+m即可,然后我们再去复制每个哨兵一次,其区间的值都+m

然后我们就跑ST表,表示从i开始往后2^j次方能够达到什么位置,如果是当前这个人的左区间+m的位置,那么就说明覆盖了整个哨所,那就是可以了,我们需要去处理一下

然后直接写即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
int l,r;
struct node{int l;int r;int pos;
}a[400005];
int st[400005][25];
int sum[400004];
bool cmp(node a,node b)
{return a.l<b.l;
}
signed main()
{cin>>n>>m;for(int i=1;i<=n;i++){cin>>l>>r;if(l>r){r+=m;}a[i].l=l;a[i].r=r;a[i].pos=i;}sort(a+1,a+1+n,cmp);for(int i=1;i<=n;i++){a[i+n].l=a[i].l+m;a[i+n].r=a[i].r+m;}for(int i=1,j=1;i<=2*n;i++){while(j<=2*n&&a[j].l<=a[i].r){j++;}st[i][0]=j-1;}for(int j=1;j<=20;j++){for(int i=1;i+(1<<j)-1<=2*n;i++){st[i][j]=st[st[i][j-1]][j-1];}}for(int i=1;i<=n;i++){int flag=a[i].l+m;int ans=0;int p=i;for(int j=20;j>=0;j--){if(st[p][j]&&a[st[p][j]].r<flag){ans+=1<<j;p=st[p][j];}}sum[a[i].pos]=ans+2;}for(int i=1;i<=n;i++){cout<<sum[i]<<" ";}return 0;
}

 Frequent values

 

思路:我们应当用到题目说的有序,我们可以将每一种数视为一个桶,然后将每个桶内的个数去求出来,然后去记录每个桶的左端点和右端点,然后我们在询问的时候,然后我们去预处理桶的数目的ST表,表示从第i个桶开始长度为2^j次方的桶内的最大值,然后我们再去找两边的最大值,然后去处理三部分最大值的最大值即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,q;
int a;
int l[500005];
int r[500005];
int st[500005][24];
int num[500005];
int x,y;
void ini()
{memset(l,0,sizeof(l));memset(r,0,sizeof(r));memset(st,0,sizeof(st));memset(num,0,sizeof(num));
}
signed main()
{while(cin>>n){if(n==0){break;}ini();cin>>q;int len=0;int flag=-0x3f3f3f3f;for(int i=1;i<=n;i++){cin>>a;if(a!=flag){r[len]=i-1;len++;l[len]=i;flag=a;}st[len][0]++;num[i]=len;}r[len]=n;for(int j=1;j<=20;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]);}}for(int i=1;i<=q;i++){cin>>x>>y;if(x>y)swap(x,y);if(num[x]==num[y]){cout<<y-x+1<<"\n";}else{int ans=0;int L=num[x]+1;int R=num[y]-1;if(L<=R){int k=0;  while((1<<(k+1))<=R-L+1) k++;ans=max(ans,max(st[L][k],st[R-(1<<k)+1][k]));}ans=max(ans,max(y-l[num[y]]+1,r[num[x]]-x+1));cout<<ans<<"\n";}}}return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/64023.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

创建vue3项目步骤以及安装第三方插件步骤【保姆级教程】

&#x1f399;座右铭&#xff1a;得之坦然&#xff0c;失之淡然。 &#x1f48e;擅长领域&#xff1a;前端 是的&#xff0c;我需要您的&#xff1a; &#x1f9e1;点赞❤️关注&#x1f499;收藏&#x1f49b; 是我持续下去的动力&#xff01; 目录 一. 简单汇总一下创建…

【PlantUML系列】部署图(七)

一、部署图的组成部分 节点&#xff08;Node&#xff09;&#xff1a;使用node关键字定义一个节点&#xff0c;节点可以是服务器、数据库或其他硬件设备。组件&#xff08;Component&#xff09;&#xff1a;使用component关键字定义一个组件&#xff0c;组件可以是软件模块或服…

【JAVA】旅游行业中大数据的使用

一、应用场景 数据采集与整合&#xff1a;全面收集旅游数据&#xff0c;如客流量、游客满意度等&#xff0c;整合形成统一数据集&#xff0c;为后续分析提供便利。 舆情监测与分析&#xff1a;实时监测旅游目的地的舆情信息&#xff0c;运用NLP算法进行智能处理&#xff0c;及…

大屏开源项目go-view二次开发3----象形柱图控件(C#)

环境搭建参考&#xff1a; 大屏开源项目go-view二次开发1----环境搭建(C#)-CSDN博客 要做的象形柱图控件最终效果如下图&#xff1a; 其实这个控件我前面的文章也介绍过&#xff0c;不过是用wpf做的&#xff0c;链接如下&#xff1a; wpf利用Microsoft.Web.WebView2显示html…

内网是如何访问到互联网(H3C源NAT)

H3C设备NAPT配置 直接打开29篇的拓扑&#xff0c;之前都配置好了 「模拟器、工具合集」复制整段内容 链接&#xff1a;https://docs.qq.com/sheet/DV0xxTmFDRFVoY1dQ?tab7ulgil 现在是出口路由器可以直接访问61.128.1.1&#xff0c;下面的终端访问不了&#xff0c;需要做NAPT源…

Linux高性能服务器编程中的TCP带外数据梳理总结

Linux高性能服务器编程中的TCP带外数据梳理总结 文章目录 Linux高性能服务器编程中的TCP带外数据梳理总结1.TCP 带外数据总结2.第五章带外数据send.crecv.c 3.第九章带外数据send.cselect.c 4.第十章带外数据send.csig_msg.c 1.TCP 带外数据总结 至此&#xff0c;我们讨论完了…

PyTorch3D 可视化

PyTorch3D是非常好用的3D工具库。但是PyTorch3D对于可用于debug&#xff08;例如调整cameras参数&#xff09;的可视化工具并没有进行系统的介绍。这篇文章主要是想介绍我觉得非常使用的PyTorch3D可视化工具。 1. 新建一个Mesh 从hugging face上下载一个glb文件&#xff0c;例…

C# 网络编程--关于UDP 通信(二)

UDP (User Datagram Protocol) 是一种无连接的传输层协议&#xff0c;主要用于支持数据报文的传输。它的主要特点包括简单、高效、不保证可靠性和顺序。 1.UDP协议基本概念 1.udp基于IP的简单的协议&#xff0c;不可靠的协议 2.优点&#xff1a;简单、 轻量化、 传输速度高、…

Axure高保真数据可视化大屏图表组件库

推出了一款高保真数据可视化大屏图表组件库&#xff0c;旨在为用户提供丰富的图表类型&#xff0c;使数据呈现更加直观、生动。本文将详细介绍该组件库中的各类图表元件&#xff0c;包括面积图、折线图、柱状图、条形图、圆环图、雷达图、仪表图以及综合类图表&#xff0c;以满…

基于视觉的3D占用网络汇总

综述文章:https://arxiv.org/pdf/2405.02595 基于视觉的3D占用预测方法的时间线概述: 自动驾驶中基于视觉的3D占用预测的分层结构分类 2023年的方法: TPVFormer, OccDepth, SimpleOccupancy, StereoScene, OccupancyM3D, VoxFormer, OccFormer, OVO, UniOcc, MiLO, Multi-…

一区向量加权算法优化INFO-CNN-SVM卷积神经网络结合支持向量机多特征分类预测

一区向量加权算法优化INFO-CNN-SVM卷积神经网络结合支持向量机多特征分类预测 目录 一区向量加权算法优化INFO-CNN-SVM卷积神经网络结合支持向量机多特征分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现INFO-CNN-SVM向量加权算法优化卷积神经网络结…

渗透测试-前端验签绕过之SHA256

本文是高级前端加解密与验签实战的第1篇文章&#xff0c;本系列文章实验靶场为Yakit里自带的Vulinbox靶场&#xff0c;本文讲述的是绕过SHA256签名来爆破登录。 绕过 通过查看源代码可以看到key为 1234123412341234通过查看源代码可以看到是通过SHA256来进行签名的&#xff0…

深入了解IPv6——光猫相关设定:DNS来源、DHCPv6服务、前缀来源等

光猫IPv6设置后的效果对比图&#xff1a; 修改前&#xff1a; 修改后&#xff1a; 一、DNS来源 1. 网络连接 来源&#xff1a; 从上游网络&#xff08;如运营商&#xff09;获取 IPv6 DNS 信息&#xff0c;通过 PPPoE 或 DHCPv6 下发。 特点&#xff1a; DNS 服务器地址直…

CentOS7下,hive4.0.0安装部署

hive安装部署 为了简单起见&#xff0c;都安装到node1服务器上。&#xff08;集群&#xff1a;node1&#xff0c;node2&#xff0c;node3&#xff09; 环境&#xff08;已安装&#xff09;&#xff1a;Hadoop3.4.0&#xff0c;jdk-8u171 需要安装&#xff1a;MySQL8.4.3&…

burp(2)利用java安装burpsuite

BurpSuite安装 burpsuite 2024.10专业版&#xff0c;已经内置java环境&#xff0c;可以直接使用&#xff0c; 支持Windows linux macOS&#xff01;&#xff01;&#xff01; 内置jre环境&#xff0c;无需安装java即可使用&#xff01;&#xff01;&#xff01; bp2024.10下载…

攻防世界逆向刷题笔记(新手模式6-?)

6.1000clicks 看题目名字似乎是让咱们点击1000次之后才会出flag。本来打算用CE看能不能搜索出来数值&#xff0c;技术不到家&#xff0c;最后没有搜索到&#xff0c;还导致永劫无间打不了了。所以还是拿出IDA老实分析。 直接搜索flag字符&#xff0c;出来一大堆。张紫涵大佬说…

CentOS 上如何查看 SSH 服务使用的端口号?

我们知道&#xff0c;linux操作系统中的SSH默认情况下&#xff0c;端口是使用22&#xff0c;但是有些线上服务器并不是使用的默认端口&#xff0c;那么这个时候&#xff0c;我们应该如何快速知道SSH使用的哪个端口呢&#xff1f; 1、通过配置文件查看 cat /etc/ssh/sshd_confi…

定时/延时任务-Kafka时间轮源码分析

文章目录 1. 概要2. TimingWheel2.1 核心参数2.2 添加任务2.3 推进时间 3. TimerTaskList3.1 添加节点3.2 删除节点3.3 刷新链表3.4 队列相关 4. 时间轮链表节点-TimerTaskEntry5. TimerTask6. Timer 和 SystemTimer - 设计降级逻辑7. 上层调用8. 小结 1. 概要 时间轮的文章&a…

厦门凯酷全科技有限公司深耕抖音电商运营

在数字经济飞速发展的今天&#xff0c;抖音电商平台以其独特的社交属性和庞大的用户基础&#xff0c;迅速成为众多品牌和商家的新战场。在这个充满机遇与挑战的市场中&#xff0c;厦门凯酷全科技有限公司凭借其专业的服务、创新的理念和卓越的执行力&#xff0c;成为了抖音电商…

探秘多AI Agent模式:机遇、应用与未来展望(5/30)

摘要&#xff1a;多 AI Agent 模式是一种强大的人工智能架构&#xff0c;它利用多个智能体&#xff08;Agent&#xff09;之间的协作与交互来解决复杂问题、执行多样化任务并模拟复杂系统行为。在这种模式中&#xff0c;每个 Agent 都具备独立的感知、决策和行动能力&#xff0…