ST表
ST表的原理及其实现
ST表类似树状数组,线段树这两种算法,是一种用于解决RMQ(Range Minimum/Maximum Query,即区间最值查询)问题的离线算法
与线段树相比,预处理复杂度同为O(nlogn),查询时间上,ST表为O(1),线段树为O(nlogn)
st表的主体是一个二维数组st[i][j],表示需要查询的数组的从下标i到下标i+2^j - 1的最值,这里以最小值为例
预处理函数:
int a[];//原始输入数组
int st[][];//st表 void init(int n)
{
for (int i = ; i < n; i++)
st[i][] = a[i]; for (int j = ; ( << j) <= n; j++)
{
for (int i = ; i + ( << j) - < n; i++)
st[i][j] = min(st[i][j - ],st[i + ( << (j - ))][j - ]);
}
}
这里首先把从0~n-1的2^0部分进行覆盖,再往下继承
继承这里也很好理解,我们以一个长度为5的数组[5,1,2,3,4]为例
2^0部分覆盖过去自然是5,4,3,2,1
2^1部分的长度为4,从0一直到3,因为从下标为4开始后面只有他自己
st[0][1]是下标为0~1的最小值,自然也就是st[0][0]和st[1][0]的最值
以此往下类推我们可以得出结论:
st[i][j] = min(st[i][j - 1],st[i + 2^(j - 1))][j - 1])
到这里初始化就完成了,注意下标不要越界,如果你对为什么这么处理有困惑的话,请继续看查询
查询函数这里不太好理解
初始化时,每一个状态对应的区间长度都为2^j,由于给出的查询区间长度不一定恰好为2^j,
所以我们要引出一个定理:2^log(a)>a/2 。
因为log(a)表示小于等于a的2的最大几次方。
比如说log(4)=2,log(5)=2,log(6)=2,log(7)=2,log(8)=3,log(9)=3…….
那么我们要查询x到y的最小值。
设len=y-x+1,t=log(len)
根据上面的定理:2^t>len/2
从位置上来说,x+2^t越过了x到y的中间!
因为位置过了一半
所以x到y的最小值可以表示为min(从x往后2^t的最小值,从y往前2^t的最小值)
前面的状态表示为mn[t][x]
设后面(从y往前2^t的最小值)的初始位置是k,
那么k+2^t-1=y,所以k=y-2^t+1
所以后面的状态表示为mn[t][y-2^t+1]
所以x到y的最小值表示为min(mn[t][x],mn[t][y-2^t+1]),所以查询时间复杂度是O(1)
int search(int l, int r)
{
int k = (int)(log((double)(r - l + )) / log(2.0));
return min(st[l][k],st[r - ( << k) + ][k]);
}
示例程序:
#include <iostream>
#include <algorithm> using namespace std; int a[];//原始输入数组
int st[][];//st表 void init(int n)
{
for (int i = ; i < n; i++)
st[i][] = a[i]; for (int i = ; ( << i) <= n; i++)
{
for (int j = ; j + ( << i) - < n; j++)
st[j][i] = min(st[j][i - ],st[j + ( << (i - ))][i - ]);
}
} int search(int l, int r)
{
int k = (int)(log((double)(r - l + )) / log(2.0));
return min(st[l][k],st[r - ( << k) + ][k]);
} int main()
{
int n,m;
while (cin >> n >> m)
{
for (int i = ; i < n; i++)
cin >> a[i]; init(n); while (m--)
{
int l, r;
cin >> l >> r;
cout << search(l,r) << endl;;
}
}
return ;
}
文章内容摘抄于:
ST表的原理及其实现 - 真是啰嗦 - 博客园
ST表算法详解
ST表的更多相关文章
- POJ3693 Maximum repetition substring [后缀数组 ST表]
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ...
- 【BZOJ-2006】超级钢琴 ST表 + 堆 (一类经典问题)
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2473 Solved: 1211[Submit][Statu ...
- 【BZOJ-3956】Count ST表 + 单调栈
3956: Count Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 173 Solved: 99[Submit][Status][Discuss] ...
- 【BZOJ-4569】萌萌哒 ST表 + 并查集
4569: [Scoi2016]萌萌哒 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 459 Solved: 209[Submit][Status] ...
- 【BZOJ-4310】跳蚤 后缀数组 + ST表 + 二分
4310: 跳蚤 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 180 Solved: 83[Submit][Status][Discuss] De ...
- HDU5726 GCD(二分 + ST表)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5726 Description Give you a sequence of N(N≤100, ...
- Hdu 5289-Assignment 贪心,ST表
题目: http://acm.hdu.edu.cn/showproblem.php?pid=5289 Assignment Time Limit: 4000/2000 MS (Java/Others) ...
- Bzoj 2006: [NOI2010]超级钢琴 堆,ST表
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2222 Solved: 1082[Submit][Statu ...
- ST表poj3264
/* ST表多次查询区间最小值 设 g[j][i] 表示从第 i 个数到第 i + 2 ^ j - 1 个数之间的最小值 类似DP的说 ans[i][j]=min (ans[i][mid],ans ...
- COJ 1003 WZJ的数据结构(三)ST表
WZJ的数据结构(三) 难度级别:B: 运行时间限制:3000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大小为N的 ...
随机推荐
- Python判断相等
判断相等方法有好几个:== .is . isinstance .issubclass .operator 模块. == :两个对象内容是否相等. >>> a = [22,44]> ...
- C#实现窗体全屏
方法一:设置窗体属性 //程序启动路径,与生成程序的exe文件在同一目录下 public String exePath = Application.StartupPath; //定义窗体宽高 ; ; ...
- Linux下批量添加用户
添加和删除用户对每位Linux系统管理员都是轻而易举的事,比较棘手的是如果要添加几十个.上百个甚至上千个用户时,我们不太可能还使用useradd一个一个地添加, 必然要找一种简便的创建大量用户的方法. ...
- Java开发笔记(六十三)双冒号标记的方法引用
前面介绍了如何自己定义函数式接口,本文接续函数式接口的实现原理,阐述它在数组处理中的实际应用.数组工具Arrays提供了sort方法用于数组元素排序,可是并未提供更丰富的数组加工操作,比如从某个字符串 ...
- 我永远爱着OOP——第二单元作业总结
第二单元的电梯真是愉♂快呢,多线程编程作为java编程OOP中的重要组成部分,通过这一个单元的学习,我也是有了很多全新的认识 那么下面就先例行一下公事 三次作业分析 第五次作业 设计分析 实现的电梯是 ...
- jQuery.Ajax IE8,9 无效(CORS跨域)
今天在开发网站的时候,发现一个问题,$.ajax()在 IE8,9 浏览器不起作用,但 Chrome,Firefox ,360,IE10以上等浏览器却是可以的,网上资料很多,查询最后发现是 IE8,9 ...
- 【转】Js正则表达式
//校验是否全由数字组成 var patrn=/^[0-9]{1,20}$/ //校验登录名:只能输入5-20个以字母开头.可带数字.“_”.“.”的字串 var patrn=/^[a-zA-Z]{1 ...
- (二)阿里云ECS Linux服务器外网无法连接MySQL解决方法(报错2003- Can't connect MySQL Server on 'x.x.x.x'(10038))(自己亲身遇到的问题是防火墙的问题已经解决)
我的服务器买的是阿里云ECS linux系统.为了更好的操作数据库,我希望可以用navicat for mysql管理我的数据库. 当我按照正常的模式去链接mysql的时候, 报错提示: - Can' ...
- 微耕N3000注入
使用ILSpy或Reflector 反编译N3000并导出解决方案,便于搜索方法代码 使用ILDASM生成中间代码D:\app\WG\AccessControl\IL\N3000.il 操作如下:(可 ...
- (转)聊聊Greenplum的那些事
开卷有益——作者的话 有时候真的感叹人生岁月匆匆,特别是当一个IT人沉浸于某个技术领域十来年后,蓦然回首,总有说不出的万千感慨. 笔者有幸从04年就开始从事大规模数据计算的相关工作,08年作为Gree ...