说一说ST表 讲一讲水题
ST表
一、算法介绍
如何快速求解RMQ问题呢?暴力复杂度O(n),线段树复杂度O(n)~O(logn),要是数据规模达到10^7或者更高呢?我们需要一种可以做到O(1)查询的算法,这时就可以用到ST表。
我们用 f[i][j] 表示从 j 位置开始往右 2^i 个数内的最大值,用 g[i][j] 表示从j位置开始往左 2^i 个数内的最大值。所以 f[0][j] , g[0][j] 就为 j 位置上的数,可以在预处理中O(n)处理掉。
接下来我们要求出每个位置的每个 2^i 区间的最大值。可以简单想到, f[1][j] = max( f[0][j] , f[0][j+1] ) , f[2][j] = max( f[1][j] , f[1][j+2]) , f[3][j] = max( f[2][j] , f[2][j+4] ) , ...... , 可以得出,f[i][j] = max( f[i-1][j] , f[i-1][j+(1<<(i-1))] ) , 同理可得, g[i][j]= max( g[i-1][j] , g[i-1][j-(1<<(i-1))] )。
对于每个查询有左端点L和右端点R,对于左端点L,从L开始能覆盖的最广而不超过右端点的倍增次数为log2(R-L+1),从右端点开始能覆盖的最广而不超过右端点的倍增次数也为log2(R-L+1),所以在[L,R]范围内最大值就为 max( f[log2(R-L+1)][L] , g[log2(R-L+1)][R] ) ,这样我们就做到了O(1)查询。
二、水题/裸题
bzoj1699
Description
每天,农夫 John 的N(1 <= N <= 50,000)头牛总是按同一序列排队. 有一天, John 决定让一些牛们玩一场飞盘比赛. 他准备找一群在对列中为置连续的牛来进行比赛. 但是为了避免水平悬殊,牛的身高不应该相差太大. John 准备了Q (1 <= Q <= 180,000) 个可能的牛的选择和所有牛的身高 (1 <= 身高 <= 1,000,000). 他想知道每一组里面最高和最低的牛的身高差别. 注意: 在最大数据上, 输入和输出将占用大部分运行时间.
Input
* 第一行: N 和 Q. * 第2..N+1行: 第i+1行是第i头牛的身高.
* 第N+2..N+Q+1行: 两个整数, A 和 B (1 <= A <= B <= N), 表示从A到B的所有牛.
Output
*第1..Q行: 所有询问的回答 (最高和最低的牛的身高差), 每行一个.
Sample Input
1
7
3
4
2
5
1 5
4 6
2 2
Sample Output
3
0
题解:用ST表算出各个区间的最大值、最小值即可。
AC代码:(写复杂了但也懒得改了)
#include <stdio.h>
#include <cmath>
#include <algorithm>
using namespace std;
int N,Q;
int h[];
int to_r_max[][],to_l_max[][];
int to_r_min[][],to_l_min[][];
int main(){
scanf("%d%d",&N,&Q);
for(int i=;i<=N;++i) scanf("%d",&h[i]);
for(int i=;i<=N;++i) to_r_max[][i]=to_l_max[][i]=to_r_min[][i]=to_l_min[][i]=h[i];
for(int i=;i<=log2(N);++i)
for(int j=;j<=N;++j){
to_r_max[i][j]=max(to_r_max[i-][j],to_r_max[i-][j+(<<(i-))]);
to_r_min[i][j]=min(to_r_min[i-][j],to_r_min[i-][j+(<<(i-))]);
to_l_max[i][j]=max(to_l_max[i-][j],to_l_max[i-][j-(<<(i-))]);
to_l_min[i][j]=min(to_l_min[i-][j],to_l_min[i-][j-(<<(i-))]);
}
for(int i=;i<=Q;++i){
int l,r;
scanf("%d%d",&l,&r);
int lenn=r-l+;
int h=max(to_r_max[int(log2(lenn))][l],to_l_max[int(log2(lenn))][r]);
int s=min(to_r_min[int(log2(lenn))][l],to_l_min[int(log2(lenn))][r]);
printf("%d\n",h-s);
}
return ;
}
说一说ST表 讲一讲水题的更多相关文章
- 没讲明白的水题orz
有一道解释程序的水题没给非计算机专业的同学讲明白orz,在这里再练一下.. 源代码完全没有缩进真是难以忍受.. p.s.懂递归就不用看了#include <stdio.h> int n = ...
- st表树状数组入门题单
预备知识 st表(Sparse Table) 主要用来解决区间最值问题(RMQ)以及维护区间的各种性质(比如维护一段区间的最大公约数). 树状数组 单点更新 数组前缀和的查询 拓展:原数组是差分数组时 ...
- Leetcode——171.Excel表列序号【水题】
@author: ZZQ @software: PyCharm @file: leetcode171_Excel表列序号.py @time: 2018/11/22 15:29 要求: 给定一个Exce ...
- skkyk:题解 洛谷P3865 【【模板】ST表】
我不会ST表 智推推到这个题 发现标签中居然有线段树..? 于是贸然来了一发线段树 众所周知,线段树的查询是log(n)的 题目中"请注意最大数据时限只有0.8s,数据强度不低,请务必保证你 ...
- [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树)
[51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树) 题面 给出一棵N个点的树,Q次询问一点编号在区间[l1,r1]内,另一点编号在区间[l2,r2]内的所有点对距离最大值.\ ...
- [bzoj4540][Hnoi2016][序列] (莫队算法+单调栈+st表)
Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,ar-1,ar.若1≤l≤s≤t≤r≤n,则称a ...
- 浅谈ST表
发现自己学的一直都是假的ST表QWQ. ST表 ST表的功能很简单 它是解决RMQ问题(区间最值问题)的一种强有力的工具 它可以做到$O(nlogn)$预处理,$O(1)$查询最值 算法 ST表是利用 ...
- ST表学习笔记
ST表是一种利用DP思想求解最值的倍增算法 ST表常用于解决RMQ问题,即求解区间最值问题 接下来以求最大值为例分步讲解一下ST表的建立过程: 1.定义 f[i][j]表示[i,i+2j-1]这个长度 ...
- ST表与树状数组
ST表 st表可以解决区间最值的问题.可以做到O(nlogn)预处理 ,O(1)查询,但是不支持修改. st表的大概思路就是用st[i][j]来表示从i开始的2的j次方个树中的最值,查询时就从左端点 ...
随机推荐
- java实现最大堆
优先队列 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除.在优先队列中,元素被赋予优先级.当访问元素时,具有最高优先级的元素最先删除.优先队列具有最高级先出 (first in, ...
- php 报错 Cannot modify header information
在用CI 开发微信公众号的时候出现下面这么个问题,网上看了一圈解决办法是:把报错的文件用editplus另存为utf-8. Severity: Warning Message: Cannot modi ...
- beta版本前准备
目录 过去存在的问题 任务分工 开发规范 后端总结 卉卉 家灿 前端总结 绪佩 青元 恺琳 宇恒 丹丹 算法&API接口 家伟 鸿杰 一好 文档&博客撰写 政演 产品功能 我们已经做了 ...
- WinDbg分析dump文件排查bug
文章:WinDbg-如何抓取dump文件 命令: cd C:\Windows\System32\inetsrv appcmd list wp 可以查看各个站点的pid
- Android使用adb命令查看CPU信息
Android中使用JNI编程的时候会需要编译出不同的SO文件,以供适配不同的机型. 例如: 由此需要查看不同机型的CPU信息. 使用ADB命令查看CPU信息命令如下: 1. adb shell 2. ...
- BZOJ 3223 Tyvj 1729 文艺平衡树 | Splay 维护序列关系
题解: 每次reverse(l,r) 把l-1转到根,r+1变成他的右儿子,给r+1的左儿子打个标记就是一次反转操作了 每次find和dfs输出的时候下放标记,把左儿子和右儿子换一下 记得建树的时候建 ...
- svn installation
# yum install mod_dav_svn.x86_64 subversion-svn2cl.noarch=========================================== ...
- 学习C++ -> 向量(vector)
一.向量的介绍 向量 vector 是一种对象实体, 能够容纳许多其他类型相同的元素, 因此又被称为容器. 与string相同, vector 同属于STL(Standard Template Lib ...
- odp.net 读写oracle blob字段
DEVELOPER: ODP.NET Serving Winning LOBs: http://www.oracle.com/technetwork/issue-archive/2005/05-nov ...
- SVN如何进行版本的还原
http://jingyan.baidu.com/article/d621e8da0d07022865913fa5.html 工具/原料 SVN乌龟软件和相关的文件 百度经验:jingyan.baid ...