专栏首页CSDN旧文『ACM-算法-ST算法』信息竞赛进阶指南--区间最值问题的ST算法

『ACM-算法-ST算法』信息竞赛进阶指南--区间最值问题的ST算法

借助倍增和动态规划可以实现O(1)的时间复杂度的查询

预处理: ①区间DP 转移方程 f[i][j] = min(MAX同理)(f[i][j - 1],f[i + ][j - 1]) f[i][j]表示从i位置开始的后2^j个数中的最大值

用f[i][j]表示从j到j+2i-1的最小值(长度显然为2i)。 任意一段的最小值显然等于min(前半段最小值,后半段最小值)。 那么f[i][j]如何用其他状态来继承呢? j到j+2i-1的长度为2i,那么一半的长度就等于2^(i-1)。 那么前半段的状态表示为f[i-1][j]。 后半段的长度也为2(i-1),起始位置为j+2(i-1)。 那么后半段的状态表示为f[i-1][j+2^(i-1)]。

②不过区间在增加时,每次并不是增加一个长度,而是基于倍增思想,用二进制右移,每次增加2^i个长度 ,最多增加logn次

这样预处理了所有2的幂次的小区间的最值

查询: ③对于每个区间,分成两段长度为的区间,再取个最值(这里的两个区间是可以有交集的,因为重复区间并不影响最值)

比如3,4,6,5,3一种分成3,4,6和6,5,3,另一种分成3,4,6和5,3,最大值都是6,没影响。

首先明确 2^log(a)>a/2 这个很简单,因为log(a)表示小于等于a的2的最大几次方。比如说log(4)=2,log(5)=2,log(6)=2,log(7)=2,log(8)=3,log(9)=3……. 那么我们要查询x到y的最小值。设len=y-x+1,t=log(len),根据上面的定理:2t>len/2,从位置上来说,x+2t越过了x到y的中间! 因为位置过了一半,所以x到y的最小值可以表示为min(从x往后2t的最小值,从y往前2t的最小值),前面的状态表示为f[t][x] 设后面(从y往前2t的最小值)的初始位置是k,那么k+2t-1=y,所以k=y-2t+1,所以后面的状态表示为f[t][y-2t+1] 所以x到y的最小值表示为f(f[t][x],f[t][y-2^t+1]),所以查询时间复杂度是O(1)

④所以O(nlogn)预处理,O(1)查询最值 但不支持修改 预处理时间复杂度O(nlogn),查询时间O(1)。

void ST_prework() {
	for (int i = 1; i <= n; i++) f[i][0] = a[i];
	int t = log(n) / log(2) + 1;
	for (int j = 1; j < t; j++)
		for (int i = 1; i <= n - (1<<j) + 1; i++)
			f[i][j] = max(f[i][j-1], f[i + (1<<(j-1))][j-1]);
}

int ST_query(int l, int r) {
	int k = log(r - l + 1) / log(2);
	return max(f[l][k], f[r - (1<<k) + 1][k]);
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 疯子的算法总结14--ST算法(区间最值)

    预处理: ①区间DP   转移方程  f[i][j] = min(MAX同理)(f[i][j - 1],f[i + ][j - 1])  f[i][j]表示从...

    风骨散人Chiam
  • 数学--矩阵快速幂详解

    风骨散人Chiam
  • POJ 2456 Aggressive cows

    Aggressive cows Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 248...

    风骨散人Chiam
  • 滚动查看日志文件与tail命令

    Spaceack
  • nginx反向代理中的相关IP

    场景一: 没有使用反向代理 配置nginx.conf,添加/修改 log 相关配置如下:

    qsjs
  • HDU-1054 Strategic Game(树形DP)

    Strategic Game Time Limit : 20000/10000ms (Java/Other) Memory Limit : 65536/32...

    ShenduCC
  • 【PAT乙级】A + B和C

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    喜欢ctrl的cxk
  • 基础练习 分解质因数

      每行输出一个数的分解,形如k=a1*a2*a3...(a1<=a2<=a3...,k也是从小到大的)(具体可看样例)

    刘开心_1266679
  • 深度解析某头条的一道面试题

    请问,如果实时展现热门文章,比如近8小时点击量最大的文章前100名。 如果是你来开发这个功能,你怎么做?

    老钱
  • 归并排序

    将两个或两个以上有序的数列(或有序表),合并成一个仍然有序的数列(有序表),这种操作称为归并操作。这样的方法经常用于多个有序的数据文件归并成一个有序的数据文件。...

    attack

扫码关注云+社区

领取腾讯云代金券