博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ3264 Balanced Lineup
阅读量:4504 次
发布时间:2019-06-08

本文共 854 字,大约阅读时间需要 2 分钟。

经典的RMQ题目。RMQ问题是求给定区间中的最值问题。朴素算法是O(n)的,用线段树可以将算法优化到O(logn)(在线段树中保存线段的最值)。

不过,只查询的话RMQ算法最合适:它可以在O(nlogn)的预处理以后实现O(1)的查询效率。线段树主要的区别是可以修改区间,RMQ不行。

下面把Sparse Table算法分成预处理和查询两部分来说明。 使用了倍增思想。
预处理:
以求最大值为例,设d[i,j]表示[i,i+2^j-1]这个区间内的最大值,那么在询问到[a,b]区间的最大值时答案就是max(d[a,k], d[b-2^k+1,k]),其中k是满足2^k<=b-a+1(即长度)的最大的k,即k=[ln(b-a+1)/ln(2)]。
d的求法可以用动态规划,d[i, j]=max(d[i, j-1],d[i+2^(j-1), j-1])。
所以我们可以采用自底向上的算法递推地给出所有符合条件的d(i, j)的值。

查询:

查询的巧妙之处是将[m, n]这段分成两个部分重叠的的区间
于是我们就可以把[m, n]分成两个(部分重叠的)长度为2^k的区间: [m, m+2^k-1], [n-2^k+1, n];

此题几个注意的地方:1. 要注意递推的时候按长度从2^0到2^j递推,j的循环要放在外面;2. log函数用的时候,里面参数是double;3. 求2的power是常用操作,使用左移<<操作非常合适;4. cin/cout会超时,要使用scanf/printf。

#include 
#include
using namespace std;#define LEN 50005#define LOG_LEN 20#define MAX(a,b) (a>b?a:b)#define MIN(a,b) (a

  

 

转载于:https://www.cnblogs.com/lautsie/p/3366627.html

你可能感兴趣的文章
Vulkan的分层设计
查看>>
WCF 定义SOAP和REST风格的webservice
查看>>
关于display
查看>>
图片懒加载
查看>>
tomcat下jndi的三种配置方式
查看>>
JS moveStart和moveEnd方法(TextRange对象--查找与选择)
查看>>
textArea中的placeholder属性不起作用
查看>>
Swift 里字符串(一)概览
查看>>
温故知新 javascript 正则表达式(转载)
查看>>
XP系统无法远程桌面
查看>>
正确使用索引
查看>>
java多态
查看>>
盒覆盖 算法
查看>>
bzoj1260 [CQOI2007]涂色paint
查看>>
仿网上银行虚拟键盘脚本- keyboard.js
查看>>
makefile "=" ":=" "?=" "+="
查看>>
机会是留给有准备的人
查看>>
实战是最好的学习方式
查看>>
使用qemu-img创建虚拟磁盘文件
查看>>
JDBC
查看>>