ST表基础模板

ST表是用来求RMQ问题(求区间最大或最小值问题)的实用数据结构,支持\(O(nlog_n)\)建立,\(O(1)\)查询,是比较高效的结构
其原理实质上是DP(我最讨厌的东西)
题面:屠龙宝刀...
这是一道ST表经典题——静态区间最大值
请注意最大数据时限只有0.8s,数据强度不低,请务必保证你的每次查询复杂度为 O(1)
本题所需处理仔细琢磨琢磨就是DP,先完成范围小一些的任务,然后再进行状态转移
转移方程(就是完成左右两区间处理后合并):
\(f_{i,j}=max(f_{i,j-1},f_{i+2^{j-1},j-1})\)
具体思想就是以每个节点为起点,保存此节点及往后的\(2^i\)个元素的最值,询问时进行覆盖询问,就是去小于\((r-l+1)\)的最大\(x\)满足\(2^x<(r-l+1)\)
然后进行询问:
\(ans=max(f_{i,x},f_{r-2^x+1,x})\)
当然,要预处理\(log_2^{1-n}\),用法见下面代码

#include<cstdio>
#include<algorithm>
using namespace std;
int n,m;
int log[100005],maxn[100005][35],num[100005];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&num[i]);
	log[0]=-1;
	for(int i=1;i<=n;i++){
		maxn[i][0]=num[i];
		log[i]=log[i>>1]+1;
	}
	for(int j=1;j<=log[n];j++)
		for(int i=1;i+(1<<j)-1<=n;i++)
			maxn[i][j]=max(maxn[i][j-1],maxn[i+(1<<(j-1))][j-1]);
	while(m--){
		int a,b;
		scanf("%d%d",&a,&b);
		int s=log[b-a+1];
		printf("%d\n",max(maxn[a][s],maxn[b-(1<<s)+1][s]));
	}return 0;
} 
posted @ 2019-07-02 16:51  _Alex_Mercer  阅读(188)  评论(0编辑  收藏  举报