【常用算法总结——ST表】

本文详细介绍了ST表作为一种解决区间最值问题的有效工具,包括其预处理和查询操作的实现原理及步骤,并通过三个洛谷平台上的具体题目展示了ST表的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ST表

  ST表是一种解决RMQ(区间最值问题)的强有力的工具

  它可以做到O(nlogn)预处理,O(1)查询最值。

实现

  ST表其实是一种倍增的思想,我们就拿取最大值为例:

开一个二维数组Max,其中Max[i][j]表示从第i位开始,包括第i位在内的2^j个数中最大的数,例如Max[i][1]表示第i个数和第i+1个数中大的那个数。

 

然后就类似于二分的样子,下一层也是拿两个已得到的区间的最大值作比较,然后存储。

预处理代码

1 for(int j=1;j<=21;j++)
2     {
3         for(int i=1;i+(1<<j)-1<=n;i++)
4         {
5             Max[i][j]=max(Max[i][j-1],Max[i+(1<<(j-1))][j-1]);
6         }
7     }

  为什么要先循环j呢?因为我们是一层一层向上搜的,每一层的答案需要下面的基础,所以把j放在外层,然后(1<<(j-1))就是把二进制的1向左移动(j-1)位,也就是2^(j-1)。

查询  

  查询也比较简单,我们只需要求出k=log2(r-l+1)(求2的k次幂小于这一段区间的值,并且尽可能大),然后得到两个区间,比较就行了

 

 (图片来源)

然后取最大值返回就可以了

1 int ST(int l,int r)
2 {
3     int k=log2(r-l+1);
4     return max(Max[l][k],Max[r-(1<<k)+1][k]);
5 }

既然了解了这么多,不如.......(放心,都是模板题)

洛谷P3865 【模板】ST表

 1 #include<bits/stdc++.h>
 2 #define N 100005
 3 using namespace std;
 4 int n,m;
 5 int Max[N][21];
 6 int ST(int l,int r)
 7 {
 8     int k=log2(r-l+1);
 9     return max(Max[l][k],Max[r-(1<<k)+1][k]);
10 }
11 int main()
12 {
13     cin>>n>>m;
14     for(int i=1;i<=n;i++)
15     {
16         scanf("%d",&Max[i][0]);
17     }
18     for(int j=1;j<=21;j++)
19     {
20         for(int i=1;i+(1<<j)-1<=n;i++)
21         {
22             Max[i][j]=max(Max[i][j-1],Max[i+(1<<(j-1))][j-1]);
23         }
24     }
25     int l,r;
26     for(int i=1;i<=m;i++)
27     {
28         scanf("%d%d",&l,&r);
29         printf("%d\n",ST(l,r));
30     }
31     return 0;
32 }

 

洛谷P2251 质量检测

 1 // luogu-judger-enable-o2
 2 #include<bits/stdc++.h>
 3 #define N 100005
 4 using namespace std;
 5 int n,m;
 6 int Min[N][21];
 7 int ST(int l,int r)
 8 {
 9     int k=log2(r-l+1);
10     return min(Min[l][k],Min[r-(1<<k)+1][k]);
11 }
12 int main()
13 {
14     cin>>n>>m;
15     for(int i=1;i<=n;i++)
16     {
17         scanf("%d",&Min[i][0]);
18     }
19     for(int j=1;j<=21;j++)
20     {
21         for(int i=1;i+(1<<j)-1<=n;i++)
22         {
23             Min[i][j]=min(Min[i][j-1],Min[i+(1<<(j-1))][j-1]);
24         }
25     }
26     for(int i=1;i+m-1<=n;i++)
27     {
28         printf("%d\n",ST(i,i+m-1));
29     }
30     return 0;
31 }

 

洛谷P1816 忠诚

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int Min[100005][21];
 4 int n,m;
 5 int ST(int l,int r)
 6 {
 7     int k=log2(r-l+1);
 8     return min(Min[l][k],Min[r-(1<<k)+1][k]);
 9 }
10 int main()
11 {
12     cin>>n>>m;
13     for(int i=1;i<=n;i++)
14     {
15         scanf("%d",&Min[i][0]);
16     }
17     for(int j=1;j<=21;j++)
18     {
19         for(int i=1;i+(1<<j)-1<=n;i++)
20         {
21             Min[i][j]=min(Min[i][j-1],Min[i+(1<<(j-1))][j-1]);
22         }
23     }
24     for(int i=1;i<=m;i++)
25     {
26         int l,r;
27         scanf("%d%d",&l,&r);
28         printf("%d ",ST(l,r));
29     }
30  } 

 

转载于:https://www.cnblogs.com/hualian/p/11215613.html

内容概要:该论文研究增程式电动汽车(REEV)的能量管理策略,针对现有优化策略实时性差的问题,提出基于工况识别的自适应等效燃油消耗最小策略(A-ECMS)。首先建立整车Simulink模型和基于规则的策略;然后研究动态规划(DP)算法和等效燃油最小策略;接着通过聚类分析将道路工况分为四类,并设计工况识别算法;最后开发基于工况识别的A-ECMS,通过高德地图预判工况类型并自适应调整SOC分配。仿真显示该策略比规则策略节油8%,比简单SOC规划策略节油2%,并通过硬件在环实验验证了实时可行性。 适合人群:具备一定编程基础,特别是对电动汽车能量管理策略有兴趣的研发人员和技术爱好者。 使用场景及目标:①理解增程式电动汽车能量管理策略的基本原理;②掌握动态规划算法和等效燃油消耗最小策略的应用;③学习工况识别算法的设计和实现;④了解基于工况识别的A-ECMS策略的具体实现及其优化效果。 其他说明:此资源不仅提供了详细的MATLAB/Simulink代码实现,还深入分析了各算法的原理和应用场景,适合用于学术研究和工业实践。在学习过程中,建议结合代码调试和实际数据进行实践,以便更好地理解策略的优化效果。此外,论文还探讨了未来的研究方向,如深度学习替代聚类、多目标优化以及V2X集成等,为后续研究提供了思路。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值