RMQ问题ST算法 (还需要进一步完善)
/*
RMQ(Range Minimum/Maximum Query)问题:
RMQ问题是求给定区间中的最值问题。当然,最简单的算法是O(n)的,但是对于查询次数很多(设置多大100万次),O(n)的算法效率不够。可以用线段树将算法优化到O(logn)(在线段树中保存线段的最值)。不过,Sparse_Table算法才是最好的:它可以在O(nlogn)的预处理以后实现O(1)的查询效率。下面把Sparse Table算法分成预处理和查询两部分来说明(以求最小值为例)。 预处理:
预处理使用DP的思想,f(i, j)表示[i, i+2^j - 1]区间中的最小值,我们可以开辟一个数组专门来保存f(i, j)的值。
例如,f(0, 0)表示[0,0]之间的最小值,就是num[0], f(0, 2)表示[0, 3]之间的最小值, f(2, 4)表示[2, 17]之间的最小值
注意, 因为f(i, j)可以由f(i, j - 1)和f(i+2^(j-1), j-1)导出, 而递推的初值(所有的f(i, 0) = i)都是已知的
所以我们可以采用自底向上的算法递推地给出所有符合条件的f(i, j)的值。 查询:
假设要查询从m到n这一段的最小值, 那么我们先求出一个最大的k, 使得k满足2^k <= (n - m + 1).
于是我们就可以把[m, n]分成两个(部分重叠的)长度为2^k的区间: [m, m+2^k-1], [n-2^k+1, n];
而我们之前已经求出了f(m, k)为[m, m+2^k-1]的最小值, f(n-2^k+1, k)为[n-2^k+1, n]的最小值
我们只要返回其中更小的那个, 就是我们想要的答案, 这个算法的时间复杂度是O(1)的.
例如, rmq(0, 11) = min(f(0, 3), f(4, 3))
*/ #include<iostream>
#include<cmath>
using namespace std;
#define MAXN 1000000
#define mmin(a, b) ((a)<=(b)?(a):(b))
#define mmax(a, b) ((a)>=(b)?(a):(b)) int num[MAXN];
int f1[MAXN][];
int f2[MAXN][]; //测试输出所有的f(i, j)
void dump(int n)
{
int i, j;
for(i = ; i < n; i++)
{
for(j = ; i + (<<j) - < n; j++)
{
printf("f[%d, %d] = %d\t", i, j, f1[i][j]);
}
printf("\n");
}
for(i = ; i < n; i++)
printf("%d ", num[i]);
printf("\n");
for(i = ; i < n; i++)
{
for(j = ; i + (<<j) - < n; j++)
{
printf("f[%d, %d] = %d\t", i, j, f2[i][j]);
}
printf("\n");
}
for(i = ; i < n; i++)
printf("%d ", num[i]);
printf("\n");
} //sparse table算法
void st(int n)
{
int i, j, k, m;
k = (int) (log((double)n) / log(2.0));
for(i = ; i < n; i++)
{
f1[i][] = num[i]; //递推的初值
f2[i][] = num[i];
}
for(j = ; j <= k; j++)
{ //自底向上递推
for(i = ; i + ( << j) - < n; i++)
{
m = i + ( << (j - )); //求出中间的那个值
f1[i][j] = mmax(f1[i][j-], f1[m][j-]);
f2[i][j] = mmin(f2[i][j-], f2[m][j-]);
}
}
} //查询i和j之间的最值,注意i是从0开始的
void rmq(int i, int j)
{
int k = (int)(log(double(j-i+)) / log(2.0)), t1, t2; //用对2去对数的方法求出k
t1 = mmax(f1[i][k], f1[j - (<<k) + ][k]);
t2 = mmin(f2[i][k], f2[j - (<<k) + ][k]);
printf("%d\n",t1 - t2);
} int main()
{
int i,N,Q,A,B;
scanf("%d %d", &N, &Q);
for (i = ; i < N; ++i)
{
scanf("%d", num+i);
} st(N); //初始化
//dump(N); //测试输出所有f(i, j)
while(Q--)
{
scanf("%d %d",&A,&B);
rmq(A-, B-);
}
return ;
}
RMQ问题ST算法 (还需要进一步完善)的更多相关文章
- RMQ的ST算法
·RMQ的ST算法 状态设计: F[i, j]表示从第i个数起连续2^j个数中的最大值 状态转移方程(二进制思想): F[i, j]=max(F[i,j-1], ...
- RMQ(ST算法)
RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列a,回答若干询问RMQ(A,i,j)(i, j<=n),返回数列a中下标在i ...
- RMQ问题——ST算法
比赛当中,常会出现RMQ问题,即求区间最大(小)值.我们该怎样解决呢? 主要方法有线段树.ST.树状数组.splay. 例题 题目描述 2008年9月25日21点10分,酒泉卫星发射中心指控大厅里,随 ...
- RMQ之ST算法模板
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; ; ],M ...
- RMQ问题+ST算法
一.相关定义 RMQ问题 求给定区间的最值: 一般题目给定许多询问区间. 常见问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大 ...
- [总结]RMQ问题&ST算法
目录 一.ST算法 二.ST算法の具体实现 1. 初始化 2. 求出ST表 3. 询问 三.例题 例1:P3865 [模板]ST表 例2:P2880 [USACO07JAN]平衡的阵容Balanced ...
- RMQ 问题 ST 算法(模板)
解决区间查询最大值最小值的问题 用 $O(N * logN)$ 的复杂度预处理 查询的时候只要 $O(1)$ 的时间 这个算法是 real 小清新了 有一个长度为 N 的数组进行 M 次查询 可 ...
- Round #4 RMQ问题ST算法
前几天群里看到有人问[JSOI2008]最大数,一道很简单的问题,线段树无脑做,但是看到了动态ST,emmm,学学吧,听大佬说了下思路,还好,不难的: 四道题都可以用其他数据结构或做法代替,例如线段树 ...
- RMQ之ST算法
#include <stdio.h> #include <string.h> ; int a[N]; ]; inline int min(const int &a, c ...
随机推荐
- ZOJ 1202 Divide and Count
原题链接 题目大意:某人手上有一大批钻石,他同时有一些盒子恰好放下这些钻石,每个盒子可以放一个或多个,问一共有几种方法. 解法:这其实是一道排列与组合计算题,主要是写出组合算法的代码,把计算公式转为程 ...
- SQL注入测试平台 SQLol -3.INSERT注入测试
访问首页的insert模块,http://127.0.0.1/sql/insert.php,开始对insert模块进行测试. insert语句: INSERT INTO [users] ([usern ...
- 转:struts标签之select详解
<html:select>生成HTML<select>元素 <html:option>:生成HTML<option>元素 <html:option ...
- 关于sql where id in 转换成数据类型 int 时失败(转)
有执行sql条件语句where id in(@参数)的时候,如果处理不当,就会出现问题:如下面这个存储过程: alter proc Web_gettwtwgoldgameserverGoldSell@ ...
- python--迭代--7
原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/ 一.什么是迭代 在Python中,如果给定一个list或tuple,我们可以通过for循环来遍历 ...
- VK Cup 2012 Round 3 (Unofficial Div. 2 Edition)
VK Cup 2012 Round 3 (Unofficial Div. 2 Edition) 代码 VK Cup 2012 Round 3 (Unofficial Div. 2 Edition) A ...
- java多线程之:创建开启一个线程的开销
---->关于时间,创建线程使用是直接向系统申请资源的,这里调用系统函数进行分配资源的话耗时不好说.---->关于资源,Java线程的线程栈所占用的内存是在Java堆外的,所以是不受jav ...
- NetStatusEvent info对象的状态或错误情况的属性
代码属性 级别属性 意义 "NetStream.Buffer.Empty" "status" 数据的接收速度不足以填充缓冲区.数据流将在缓冲区重新填充前中 ...
- Attention and Augmented Recurrent Neural Networks
Attention and Augmented Recurrent Neural Networks CHRIS OLAHGoogle Brain SHAN CARTERGoogle Brain Sep ...
- JSBinding + SharpKit / 实战:转换 Stealth
这个例子相对简单,基本上一路顺畅 // JSBindingSettings.classes public static Type[] classes = new Type[] { typeof(Per ...