ST表

ST表

ST表可以 O(nlogn)O(nlogn) 预处理,O(1)O(1) 查询最值

解决RMQ(区间求最值)的问题

f[i][j] 代表从i开始长度为 2j 的序列的最大值(或最小值,下文以最大值为例)

例题 洛谷P3865

题目描述

给定一个长度为 N 的数列,和 M 次询问,求出每一次询问的区间内数字的最大值。

输入格式

第一行包含两个整数 N,M,分别表示数列的长度和询问的个数。

第二行包含 N 个整数(记为 ai),依次表示数列的第 i 项。

接下来 M 行,每行包含两个整数 li,ri,表示查询的区间为 [li,ri]

输出格式

输出包含 M 行,每行一个整数,依次表示每一次询问的结果。

代码

根据数学知识可以转换,2s=n 可以转化为 (10x)s=n,其中 x=log10(2) ,xs=log10(n),则 s=log10(n)/log10(2);

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m,f[100010][50],l,r;//f[i][j]代表从i开始长度为2^j的序列的最大值
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&f[i][0]);
	}
	int s=log(n)/log(2);//由数学知识可求
	for(int j=1;j<=s;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]);//f[][j-1]已经计算
		}
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d",&l,&r);
		int k=log(r-l+1)/log(2);
		printf("%d\n",max(f[l][k],f[r-(1<<k)+1][k]));
	}
	return 0;
}
posted @   muzqingt  阅读(22)  评论(3编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示