算法笔记--st表
2024-10-20 11:49:26
概述:用倍增法求区间最值的离线算法,O(nlogn)预处理,O(1)访问。
预处理:
状态:st[i][j]:[i,i+2^j)之间的最值
状态转移:如果j等于0,st[i][j]=a[i]
如果j大于0,st[i][j]=max(st[i][j-1],st[i+2^(j-1)][j-1])或st[i][j]=min(st[i][j-1],st[i+2^(j-1)][j-1])
访问:
求[l,r]区间里的最值
k=floor(log(r-l+1))
ans=max(st[l][k],st[r-2^k+1][k])或ans=min(st[l][k],st[r-2^k+1][k])
模板:
int st[N][],a[N];
void init_st(int n){
for(int i=n;i>=;i--){
st[i][]=a[i];
for(int j=1;i+(<<j-)-<=n;j++){
st[i][j]=min(st[i][j-],st[i+(<<j-)][j-]);
}
}
}
int query(int l,int r){
int k=floor(log(r-l+)/log());
return min(st[l][k],st[r-(<<k)+][k]);
}
例题:POJ - 3264
思路:求区间最值差
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a)) const int N=1e5+;
int ss[N][],st[N][],a[N];
void init_st(int n){
for(int i=n;i>=;i--){
st[i][]=a[i];
ss[i][]=a[i];
for(int j=;i+(<<j-)-<=n;j++){
st[i][j]=min(st[i][j-],st[i+(<<j-)][j-]);
ss[i][j]=max(ss[i][j-],ss[i+(<<j-)][j-]);
}
}
}
int query(int l,int r){
int k=floor(log(r-l+)/log());
return max(ss[l][k],ss[r-(<<k)+][k])-min(st[l][k],st[r-(<<k)+][k]);
}
int main(){
ios::sync_with_stdio(false);
cin.tie();
int n,q,l,r;
cin>>n>>q;
for(int i=;i<=n;i++)cin>>a[i];
init_st(n);
while(q--){
cin>>l>>r;
cout<<query(l,r)<<endl;
}
return ;
}
参考:https://www.cnblogs.com/AireenYe/p/6270518.html
最新文章
- wpf 逻辑树与可视化树
- ArcGIS将Nodata区设置为0
- BADI_MATERIAL_CHECK(物料主数据表的增强检查)
- Google Play笔记之上架
- 在CentOS上搭建PHP服务器环境
- KALI LINUX WEB 渗透测试视频教程—第16课 BEEF基本使用
- C#中使用JQueryUI中Autocomplete插件
- 一个新人对于JavaScript简单应用的理解
- boost之function
- Android监听WIFI网络的变化并且获得当前信号强度
- thead、tbody、tfoot与顺序无关
- android环境搭配 运行android sdk manager时出现错误问题解决
- 《火球——UML大战需求分析》(0.1)——开篇废话
- 使用SpringSecurity保护你的Eureka.
- [题解]NOIP2018(普及组)T1标题统计(title)
- dbms_redefinition方式普通表改造分区表
- Spring+Quartz 实现定时任务的配置方法
- MyBatis的javaType和ofType的区别
- ios处理键盘
- BZOJ3771: Triple【生成函数】