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 ...
随机推荐
- Matlab神经网络工具箱学习之二
螃蟹的分类 这个例子的目的是根据螃蟹的品种.背壳的长宽等等属性来判断螃蟹的性别,雄性还是雌性. 训练数据一共有六个属性: species, frontallip, rearwidth, length, ...
- ZOJ 1078 Palindrom Numbers
原题链接 题目大意:判断一个数是不是palindrom.不限于十进制,可以在任何进制下判断. 解法:还好,数字的范围不大,int类型足够搞定.方法就是从2进制开始,先把数字转换成2进制,判断是否对称, ...
- Android开源项目大全之工具库
http://www.neast.cn/forum.php?mod=viewthread&tid=5487&fromuid=5
- leetcode 126. Word Ladder II ----- java
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...
- poj3259 最短路判环
题意:有一些点.一些道路和一些虫洞,道路是双向的,连接两点,花费正的时间,而虫洞是单向的,连接两点,可以使时间倒退,求是否能够回到过去. 只要明确回到过去其实就是当出现一个负环的时候,不断沿这个环走, ...
- Oracle学习系列2
SQL语法练习: 1,选择部门30中的所有员工 select * from emp where deptno=30; 2,列出办事员的姓名,编号和部门编号 select ename, empno, d ...
- Anroid 异常:is not valid; is your activity running?
本文转载于:http://blog.csdn.net/biangren/article/details/7514722 是由于有activity时依附于另一个activity的,当被依附的activi ...
- NGUI Font
---------------------------------------------------------------------------------------------------- ...
- 怎么用ABBYY创建属于自己的PDF
怎么创建一份属于自己的PDF文档呢?由于PDF格式文件具有跨平台.支持超长文件.安全可靠性高等诸多优势,在日常办公学习中应用越来越广泛.而随着技术的发展,各种办公软件也对PDF提供越来越多的支持,但P ...
- linux服务之smtp
实现这个协议的软件太多,有sendmail,postfix等.不像snmp,基本上是net-snmp一统天下, yum install nc nc用来取代telnet 这里我们希望让大家知道网络协议中 ...