随笔- 22  文章- 0  评论- 10  阅读- 1579 

ST表

简介

ST表是一种可进行快速的区间查询的数据结构。他的预处理复杂度为O (nlogn),查询复杂度为O(1)。
ST表能解决可重复贡献问题,即某段区间被重复计算不会影响结果。

实现

初始化

定义状态f[i,j]表示下标ii+2j1的数据的结果,共2i个元素
转移时可将f[i,j]分成相等两份f[i,j1]f[i+2j1,j1]f[i,j]便从f[i,j1]f[i+2j1,j1]转移过来
以求区间最大值为例:
f[i,j]=max(f[i,j1],f[i+2j1,j1])

查询

假设要查询区间[l,r]里的最大值,那么我们需要找到恰好能覆盖这一区间的f。设k=log2(rl+1),则区间[l,r]可分为[l,l+2k][r2k+1,r]两部分,即f[l,k]f[r2k+1,k]两部分。答案就是这两部分取个max

代码

#include<bits/stdc++.h>
using namespace std;
int st[200010][20]={0},a[100010];
int n,m,l,r;
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		st[i][0]=a[i];//初始化边界条件
	}
	for(int i=n;i>=1;i--)
	{
		for(int j=1;j<20;j++)
		{
			if((i+(1<<(j-1)))>n)continue;//如果越界就跳过
			st[i][j]=st[i][j-1]>st[i+(1<<(j-1))][j-1]?st[i][j-1]:st[i+(1<<(j-1))][j-1];//状态转移
		}
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&l,&r);
		int k=log2(r-l+1),ans;
		ans=(st[l][k]>st[r-(1<<k)+1][k])?st[l][k]:st[r-(1<<k)+1][k];//求出答案
		printf("%d\n",ans);
	}
    return 0;
}
 posted on   hu_led  阅读(106)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示