说一说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次方个树中的最值,查询时就从左端点 ...
随机推荐
- Python全栈工程师(exercises)
# # 练习: # # 1. 用map函数求: # # 1**3 + 2**3 + 3 ** 3 + .... 9**3 的和 def add_(x): return x ** 3 print(sum ...
- 【Linux】wc :字数统计命令
wc :(Word Count) 统计每个传入文件中行数.词数与字节数 $ wc py_this # 三个数字分别对应行数.词数和字节数 21 144 857 py_this $ wc py_this ...
- Java UDP的简单实例以及知识点简述
UDP的实现 Java中实现UDP协议的两个类,分别是DatagramPacket数据包类以及DatagramSocket套接字类. 其与TCP协议实现不同的是: UDP的套接字DatagramSoc ...
- iOS大神班笔记02-模仿苹果创建单例
首先我们得要知道苹果是如何实现单例的:1.不能外界调用alloc,一调用就崩掉,其实就是抛异常(类内部第一次调用alloc就不崩溃,其他都崩溃). 2.提供一个方法给外界获取单例. 3.内部创建一次 ...
- [洛谷P3810]【模板】三维偏序(陌上花开)
题目大意:有$n$个元素,第$i$个元素有三个属性$a_i,b_i,c_i$,设$f(i)=\sum\limits_{i\not = j}[a_j\leqslant a_i,b_j\leqslant ...
- 详解Django-auth-ldap 配置方法
使用场景 公司内部使用Django作为后端服务框架的Web服务,当需要使用公司内部搭建的Ldap 或者 Windows 的AD服务器作为Web登录认证系统时,就需要这个Django-auth-ldap ...
- [hdu] 5696 区间的价值 || 序列分治
原题 我们定义"区间的价值"为一段区间的最大值*最小值. 一个区间左端点在L,右端点在R,那么该区间的长度为(R−L+1). 求长度分别为1-n的区间的最大价值. 保证数据随机 因 ...
- 洛谷树剖模板题 P3384 | 树链剖分
原题链接 对于以u为根的子树,后代节点的dfn显然比他的dfn大,我们可以记录一下回溯到u的dfn,显然这两个dfn构成了一个连续区间,代表u及u的子树 剩下的就和树剖一样了 #include< ...
- 【BZOJ 5000 OI树】
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 107 Solved: 64[Submit][Status][Discuss] Description ...
- ACM童年生活二三事
描述 Redraiment小时候走路喜欢蹦蹦跳跳,他最喜欢在楼梯上跳来跳去. 但年幼的他一次只能走上一阶或者一下子蹦上两阶. 现在一共有N阶台阶,请你计算一下Redraiment从第0阶到第N阶共有几 ...