2018/2/17 每日一学 RMQ

什么是RMQ?

给予n个数,对于区间[l,r]查询最小、最大值。

这就是RMQ。

怎么做?

我们不妨设f[i][j]表示从i开始的2^j个数极值。

显然,他表示的是[i,i+2^j-1],注意有-1(想想,为什么?)

那么我们不难得到递推式:f[i][j]=min/max(f[i][j-1]+f[i+1<<(j-1)+1][j-1]。

注意先枚举j,联系以下区间dp不难明白为什么先枚举j。

最后怎么查询???

很简单,分治的思想。

假设我们查询[x,y],则ans=max/min([x][k],[y-1<<k+1][k].

这个k怎么求,由题意得:x+2^k>=y-2^k+1.

得,y-x+1<=2^(k+1)

所以就很简单了,k=log2(y-x+1)

看代码吧:

void ST(int n) {
    for (int i = 1; i <= n; i++)
        dp[i][0] = A[i];
    for (int j = 1; (1 << j) <= n; j++) {
        for (int i = 1; i + (1 << j) - 1 <= n; i++) {
            dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
        }
    }
}
int RMQ(int l, int r) {
    int k = 0;
    while ((1 << (k + 1)) <= r - l + 1) k++;
    return min(dp[l][k], dp[r - (1 << k) + 1][k]);
}

原文地址:https://www.cnblogs.com/Alex-leaves/p/8453500.html

时间: 2024-10-11 22:28:55

2018/2/17 每日一学 RMQ的相关文章

2018/04/17 每日一个Linux命令 之 tar

10天没有更新这个每日学习 linux 了,因为实在很忙,晚上还要看会其他知识. 但是也不应该给自己找理由,还是应该每天的坚持下去 -- tar 用于在 linux 解压缩/文件 这个命令下面的参数非常多,想看的可以去看下,这里只写出常用的解压缩命令. Linux tar命令 -- 压缩 例如我们要把 /etc 目录打包 1:打包文件目录为 .tar 包 tar -cvf /tmp/etc.tar /etc <==仅打包,不压缩! 2:打包目录并且使用  gzip 压缩 tar -zcvf /t

2018/2/10 每日一学 差分约束算法

差分约束算法 我们知道,对于一个最短路问题中的某边<u,v>,必定有d[v]<=d[u]+w,稍稍变形可得d[v]-d[u]<=w,是不是很像x1-x2<=a这种数学不等式? 所以对于一不等式组,我们可以将其转化为x1-x2<=a形式,连接一条有向边(X2->X1),权值为a,然后求最短路就行了. 注意如果对于负环的判断以及图的连通判断-- 刷点题再看看吧. 原文地址:https://www.cnblogs.com/Alex-leaves/p/8439751.ht

2018/2/11 每日一学 无向图割顶和桥

割顶和桥:对于无向图G,如果删除某个节点u后,连通分量数目增加,则称u为图的割顶:如果删除某条边后,连通分量数目增加,则称该边为图的桥. 对于连通图删除割顶或桥后都会使得图不再连通. 我们利用dfs的性质来快速找出一个连通图中的所有的割顶和桥. 设low[u]为u及其后代所能连回的最早的祖先的pre[]值,pre[]为时间戳则当u存在一个子节点v使得low[v] >= pre[u]时u就为割顶 同理当 low[v] > pre[u]时 u-v为桥 看代码吧(转自http://blog.csdn

2018/2/12 每日一学 三分搜索

对于二分,设left,right为问题的两个极值,用min=left+(right-left)>>1或mid=(left+right)>>1,可以知道mid值,判断,然后进行更换. 显然,二分适用于单调函数,而对于一个二次函数就无效了. 这时,我们可以用三分搜索来做. 我们定义midl=(left+mid)>>1,midr=(right+mid)>>1.判断midl和midr就行了. 看看代码吧:(转自http://blog.csdn.net/u011787

2018/2/16 每日一学 A*搜索

A*搜索 我们知道dfs和bfs在搜索中会搜素一些完全不会搜的点,这是因为,他们只考虑到起点到当前点的作用,未考虑到终点. 我们不妨设f[i]=g[i]+h[i],其中g[i]为到i的最短路(已知),h[i]为i到终点的估计值.所以说,我们用f[i]做bfs 每次取出f最小的i,拓展,然后直到终点-- 那么h[i]怎么求?? 我们可以用曼哈顿距离或者欧式距离等等来表示,注意我们要用二叉堆来维护f数组. 代码目前网上很多,就不写了. 原文地址:https://www.cnblogs.com/Ale

2018/2/22 每日一学 AC自动机

AC自动机=trie树+KMP. 代码如下:(自行理解) #include<cstdio> #include<string.h> #include<math.h> #include<queue> #include<algorithm> #define N 500006 using namespace std; char st[1000005]; char keyword[55]; int n,m; int next[N][26],cnt[N],f

2018/2/24 每日一学 字符串最小表示法

非常简单,直接上代码: int minimalRepresentation() { int n = strlen(str); int i = 0,j = 1, k = 0; while(i<n && j<n && k<n) { int t = str[(i+k)%n] - str[(j+k)%n] ; if(t == 0) k++; else { if(t>0) i+=k+1; else j+=k+1; if(i==j) j++; k = 0; }

2018/03/07 每日一学PHP 之 常量defind 和 const区别

什么是常量? 如字面理解的,在脚本执行期间不可改变的的量. 定义一个常量应该注意的事项? 1:常量默认大小写敏感,错误的大小写不会被识别为常量. 2:常量只能是标量数据,也可以定义 资源 常量,但是定义了,会发生一些奇妙的,不可预知的错误,所以应当尽量避免. 标量数据:(boolean,integer,float 和 string) 通过 defind 和 const 区别 1:重复定义 1:defind 重复定义常量,常量不会被修改,php报一个 通知 错误: 报错: 结论: 虽不影响程序运行

2018/03/10 每日一学PHP 之 修饰符 public/private/protected

对于面向对象 修饰符的使用是我们最常用,也是很容易忽略的小细节. 对于编程来说,把握好每一个小细节,就能构造出漂亮,优雅的程序. public 使用最多的修饰符,公共方法,允许所有访问,就像一个公交车一样,上来交钱[参数],有钱就行,无所谓是谁. 对于这个修饰符救不在做更多的解释了,因为他的使用实在是太多了. PS:如果一个方法没有定义修饰符,那么在PHP5中,默认是public. private 私有方法, 不允许在直接实例化后访问,子类也不能直接访问,只允许在自己的类中使用. 道理我都懂,我