#include <bits/stdc++.h>

using namespace std;
const int maxn=1e6+7;
int st[maxn][32];
int a[maxn],n;
void init(){
int i,j;
//st[i][j]表示i到i+2^j-1区间的最小值
//先预处理区间长度为1的
for(i=0;i<n;++i) st[i][0]=a[i];
for(i=0;i<n;++i){
for(j=1;i+2^(j)-1<n;++j){
//i~i+2^(j-1)-1
//i+2^(j-1)~i+2^(j-1)+2^(j-1)-1=>i+2^j-1;
//一定要发现这个显然的事实就是
//2^(j-1)+2^(j-1)=2^j;
st[i][j]=min(s[i][j-1],s[i+2^(j-1)][j-1]);
}
}
}
int queryMin(int l,int r){
int len=r-1+1;
int index=log(len);
//st[l][index] l~l+2^(index)-1
//2^(index)<=(r-l+1); l+2^(index)-1<=r
//r-(l+2^(index)-1)>=0 还差多少元素没放进来
//x+LEN=l+2^(index)-1+(r-(l+2^(index)-1));
//x+2^(index)-1=r;//区间长度固定。。起点是多少才能正好跑到r,列一个简单的方程才能解决
//x=r+1-(2^(index));
return min(st[l][index],st[r+1-(2^(index))][index]);
}
int main(){
while(~scanf("%d",&n)){
int i,q,l,r;
for(i=0;i<n;++i){
scanf("%d",a+i);
}
init();
scanf("%d",&q);
for(i=0;i<q;++i){
scanf("%d%d",&l,&r);
printf("%d\n",query(l,r));
}
}
return 0;
}

上面这个^符号代表幂次。。而c++里只有异或。。这就是为什么这是一个伪代码的意思

先来一个终极伪代码

推导过程如上。。

下面给一个真正的的代码

#include <bits/stdc++.h>

using namespace std;
const int maxn=1e6+7;
int st[maxn][32];
int a[maxn],n;
void init(){
int i,j;
//st[i][j]表示i到i+2^j-1区间的最小值
//先预处理区间长度为1的
for(i=0;i<n;++i) st[i][0]=a[i];
for(i=0;i<n;++i){
for(j=1;i+(1<<j)-1<n;++j){//这里有一个优化。。本来是小于32的。。问题规模较小是只是相当于一个常数的优化
//i~i+2^(j-1)-1
//i+2^(j-1)~i+2^(j-1)+2^(j-1)-1=>i+2^j-1;
//一定要发现这个显然的事实就是
//2^(j-1)+2^(j-1)=2^j;
st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
}
}
int queryMin(int l,int r){
int k=log(r-l+1);
//st[l][index] l~l+2^(index)-1
//2^(index)<=(r-l+1); l+2^(index)-1<=r
//r-(l+2^(index)-1)>=0 还差多少元素没放进来
//x+LEN=l+2^(index)-1+(r-(l+2^(index)-1));
//x+2^(index)-1=r;//区间长度固定。。起点是多少才能正好跑到r,列一个简单的方程才能解决
//x=r+1-(2^(index));
return min(st[l][k],st[r+1-(1<<k)][k]);
}
int main(){
while(~scanf("%d",&n)){
int i,q,l,r;
for(i=0;i<n;++i){
scanf("%d",a+i);
}
init();
scanf("%d",&q);
for(i=0;i<q;++i){
scanf("%d%d",&l,&r);
printf("%d\n",queryMin(l-1,r-1));
}
}
return 0;
}

还有一个对于新手来说理解的坑。。那就是int x=log(val)实际上是对log的值向下取整。。这一点非常重要
只有这个成立我们注释里的推导才会成立。。另外有一些没用的推导。。但是我没有删掉。。这是因为想记录一下我全部的思考过程

关于st表的推导的更多相关文章

  1. ST表学习总结

    前段时间做16年多校联合赛的Contest 1的D题(HDU 5726)时候遇到了多次查询指定区间的gcd值的问题,疑惑于用什么样的方式进行处理,最后上网查到了ST表,开始弄得晕头转向,后来才慢慢找到 ...

  2. P6087 [JSOI2015]送礼物 01分数规划+单调队列+ST表

    P6087 [JSOI2015]送礼物 01分数规划+单调队列+ST表 题目背景 \(JYY\) 和 \(CX\) 的结婚纪念日即将到来,\(JYY\) 来到萌萌开的礼品店选购纪念礼物. 萌萌的礼品店 ...

  3. POJ3693 Maximum repetition substring [后缀数组 ST表]

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9458   Acc ...

  4. 【BZOJ-2006】超级钢琴 ST表 + 堆 (一类经典问题)

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2473  Solved: 1211[Submit][Statu ...

  5. 【BZOJ-3956】Count ST表 + 单调栈

    3956: Count Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 173  Solved: 99[Submit][Status][Discuss] ...

  6. 【BZOJ-4569】萌萌哒 ST表 + 并查集

    4569: [Scoi2016]萌萌哒 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 459  Solved: 209[Submit][Status] ...

  7. 【BZOJ-4310】跳蚤 后缀数组 + ST表 + 二分

    4310: 跳蚤 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 180  Solved: 83[Submit][Status][Discuss] De ...

  8. HDU5726 GCD(二分 + ST表)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5726 Description Give you a sequence of N(N≤100, ...

  9. Hdu 5289-Assignment 贪心,ST表

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=5289 Assignment Time Limit: 4000/2000 MS (Java/Others) ...

随机推荐

  1. 浅谈JavaScript代码性能优化2

    一.减少判断层级 从下图代码中可以明显看出,同样的效果判断层级的减少可以优化性能 二.减少作用域链查找层级 简单解释下,下图中第一个运行foo函数,bar函数内打印name,bar作用域内没有name ...

  2. Python爬虫学习笔记(一)

    概念: 使用代码模拟用户,批量发送网络请求,批量获取数据. 分类: 通用爬虫: 通用爬虫是搜索引擎(Baidu.Google.Yahoo等)"抓取系统"的重要组成部分. 主要目的是 ...

  3. 基于Python的接口自动化-unittest测试框架和ddt数据驱动

    引言 在编写接口自动化用例时,我们一般针对一个接口建立一个.py文件,一条接口测试用例封装为一个函数(方法),但是在批量执行的过程中,如果其中一条出错,后面的用例就无法执行,还有在运行大量的接口测试用 ...

  4. Failed to start LSB: starts php-fpm

    跟nginx一样都是进程占用,记录下 [root@localhost pazzn]# systemctl status php-fpm.service ● php-fpm-72.service - L ...

  5. MySQL时间格式转换函数

    MySQL DATE_FORMAT() 函数注:当前年份是2018-7-19 SELECT DATE_FORMAT(NOW(),'%Y')                                ...

  6. dij的优先队列边表优化

    dij的复杂度为v*v,通过优先队列优化后为e*logv. (第一次写,没有过多的测试,不保证对.只当是测试blog了!) #include<cstdio> #include<ios ...

  7. 大型面试现场:一条update sql执行都经历什么?

    导读 Hi,大家好!我是白日梦!本文是MySQL专题的第 24 篇. 今天我要跟你分享的MySQL话题是:"从一条update sql执行都经历什么开始,发散开一系列的问题,看看你能抗到第几 ...

  8. Java——I/O入门相关练习代码

    流的概念 读取文件 读取文件1 读取文件2 读取文件3 读取文件4 skip跳过n个字节后再开始读取 读取过程中暂停给当前位置做一个标记下一次从标记位置开始读取 序列流集合流 把三个流添加到集合中合并 ...

  9. Golang内建库学习笔记(1)-sort和container

    sort库 利用sort.Sort进行排序须实现如下接口 type Interface interface { // 获取数据集合元素个数 Len() int // 如果i索引的数据小于j所以的数据, ...

  10. CCF-有趣的数(数位DP)

    有趣的数   问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前 ...