/*
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. Dialog样式

    <style name="load_dialog" parent="@android:style/Theme.Dialog"> <item n ...

  2. hadoop常用管理员命令

    hadoop job -list 列出正在运行的job hadoop job -kill kill掉job hadoop fsck 检查HDFS坏快 hadoop dfsadmin -report检查 ...

  3. lightoj1074 最短路

    题意:有n个城市,每个城市有拥挤值,有一些单向道路,从某个城市到另一个城市的花费是拥挤值差的三次方,当然可能是负的值.问从1点到某点最少的花费,若小于3或不能到达输出“?” 建图的边权是拥挤值差的三次 ...

  4. 升级win10的理由

    微软也没给我钱,我免费给它打了次广告. 我还是非常喜欢linux的,无奈公司深度依赖windows. 废话不多说,直接进入主题: [开机速度] 这里先说句题外话,不那么缺钱的兄弟,一定要去换一块SSD ...

  5. 论文笔记之:Spatially Supervised Recurrent Convolutional Neural Networks for Visual Object Tracking

    Spatially Supervised Recurrent Convolutional Neural Networks for Visual Object Tracking  arXiv Paper ...

  6. Fixing Poor MySQL Default Configuration Values

    I've recently been accumulating some MySQL configuration variables that have defaults which have pro ...

  7. easyui datagrid 表格组件列属性formatter和styler使用方法

    明确单元格DOM结构 要想弄清楚formatter和styler属性是怎么工作的,首先要弄清楚datagrid组件内容单元格的DOM接口,注意,这里指的是内容单元格,不包括标题单元格,标题单元格的结构 ...

  8. linux服务之varnish

    https://www.varnish-cache.org/installation/redhatvarnish是现在很流行的一个HTTP(80)缓存加速解决方案,varnish是基于内存的缓存加速. ...

  9. 查看 activex 组件的方法

    查看 activex 组件的方法 可以使用的工具COMRaider 直接安装 并选择对应的类型即可查看相关的信息,比OLE/COM Object Viewer 简洁方便. 具体的操作如下: 随意选择一 ...

  10. SpringMVC的各种参数绑定方式

    1. 基本数据类型(以int为例,其他类似):2. 包装类型(以Integer为例,其他类似):3. 自定义对象类型:4. 自定义复合对象类型:5. List绑定:6. Set绑定:7. Map绑定: ...