/*
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算法 (还需要进一步完善)的更多相关文章

  1. RMQ的ST算法

    ·RMQ的ST算法    状态设计:        F[i, j]表示从第i个数起连续2^j个数中的最大值    状态转移方程(二进制思想):        F[i, j]=max(F[i,j-1], ...

  2. RMQ(ST算法)

    RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列a,回答若干询问RMQ(A,i,j)(i, j<=n),返回数列a中下标在i ...

  3. RMQ问题——ST算法

    比赛当中,常会出现RMQ问题,即求区间最大(小)值.我们该怎样解决呢? 主要方法有线段树.ST.树状数组.splay. 例题 题目描述 2008年9月25日21点10分,酒泉卫星发射中心指控大厅里,随 ...

  4. RMQ之ST算法模板

    #include<stdio.h> #include<string.h> #include<iostream> using namespace std; ; ],M ...

  5. RMQ问题+ST算法

    一.相关定义 RMQ问题 求给定区间的最值: 一般题目给定许多询问区间. 常见问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大 ...

  6. [总结]RMQ问题&ST算法

    目录 一.ST算法 二.ST算法の具体实现 1. 初始化 2. 求出ST表 3. 询问 三.例题 例1:P3865 [模板]ST表 例2:P2880 [USACO07JAN]平衡的阵容Balanced ...

  7. RMQ 问题 ST 算法(模板)

    解决区间查询最大值最小值的问题 用 $O(N * logN)$ 的复杂度预处理 查询的时候只要 $O(1)$ 的时间  这个算法是 real 小清新了   有一个长度为 N 的数组进行 M 次查询 可 ...

  8. Round #4 RMQ问题ST算法

    前几天群里看到有人问[JSOI2008]最大数,一道很简单的问题,线段树无脑做,但是看到了动态ST,emmm,学学吧,听大佬说了下思路,还好,不难的: 四道题都可以用其他数据结构或做法代替,例如线段树 ...

  9. RMQ之ST算法

    #include <stdio.h> #include <string.h> ; int a[N]; ]; inline int min(const int &a, c ...

随机推荐

  1. ZOJ 1202 Divide and Count

    原题链接 题目大意:某人手上有一大批钻石,他同时有一些盒子恰好放下这些钻石,每个盒子可以放一个或多个,问一共有几种方法. 解法:这其实是一道排列与组合计算题,主要是写出组合算法的代码,把计算公式转为程 ...

  2. SQL注入测试平台 SQLol -3.INSERT注入测试

    访问首页的insert模块,http://127.0.0.1/sql/insert.php,开始对insert模块进行测试. insert语句: INSERT INTO [users] ([usern ...

  3. 转:struts标签之select详解

    <html:select>生成HTML<select>元素 <html:option>:生成HTML<option>元素 <html:option ...

  4. 关于sql where id in 转换成数据类型 int 时失败(转)

    有执行sql条件语句where id in(@参数)的时候,如果处理不当,就会出现问题:如下面这个存储过程: alter proc Web_gettwtwgoldgameserverGoldSell@ ...

  5. python--迭代--7

    原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/ 一.什么是迭代 在Python中,如果给定一个list或tuple,我们可以通过for循环来遍历 ...

  6. 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 ...

  7. java多线程之:创建开启一个线程的开销

    ---->关于时间,创建线程使用是直接向系统申请资源的,这里调用系统函数进行分配资源的话耗时不好说.---->关于资源,Java线程的线程栈所占用的内存是在Java堆外的,所以是不受jav ...

  8. NetStatusEvent info对象的状态或错误情况的属性

      代码属性 级别属性 意义 "NetStream.Buffer.Empty" "status"  数据的接收速度不足以填充缓冲区.数据流将在缓冲区重新填充前中 ...

  9. Attention and Augmented Recurrent Neural Networks

    Attention and Augmented Recurrent Neural Networks CHRIS OLAHGoogle Brain SHAN CARTERGoogle Brain Sep ...

  10. JSBinding + SharpKit / 实战:转换 Stealth

    这个例子相对简单,基本上一路顺畅 // JSBindingSettings.classes public static Type[] classes = new Type[] { typeof(Per ...