ST表及其应用

背景

我们在求区间最大最小值时,可以暴力从l到r,也可以用线段树、树状数组,但是都没有ST表的O(logn)建立,O(1)查询快

思路

对于一个数组,我们首先知道Max[1,1],Max[2,2],Max[3,3]…Max[n,n],是不是就进一步知道了Max[1,2],Max[2,3],Max[3,4]…,然后就可以知道Max[1,4],Max[2,5],Max[3,6],Max[4,7],Max[5,8]…然后就可以知道Max[1,8],Max[9,16]…

建表

ST表用的就是一个倍增思想,所以建表时logn的,从上面可以知道ST表建立的状态转移方程是:F[i][j] = max(F[i][j-1],F[i+(1 << j-1)][j-1]);
注意我们用到了log函数,他比较慢,所以我们预处理一下

void init() {
	logn[0] = 0;
	logn[1] = 0;
	logn[2] = 1;
	for(int i=3;i<=n;i++)
		logn[i] = logn[i/2]+1;
}
void GetSt() {
	for(int i=1;i<=logn[n];i++) {
		for(int j=1;j+(1 << i)-1<=n;j++) {
			f1[j][i] = max(f1[j][i-1],f1[j+(1 << i-1)][i-1]);  
			f2[j][i] = min(f2[j][i-1],f2[j+(1 << i-1)][i-1]);        
		}
	}
}

查询

如果我们查找3-13,那么区间长度是11,但11有不是2的整数次幂,所以我们就要让查询的区间长度变成8,接着对3-10和6-13取max即可。两区间有交集,但是我们求的是最大值,允许有重复贡献

int findMin(int l,int r) {
	int x = logn[r - l + 1];//区间长度!!!!!
	return min(f2[l][x],f2[r - (1 << x) + 1][x]);
}

例题

2021牛客暑假多校(5)K: King of Range
题意:给一个数组,问有多少个子数组满足以下条件:最大值减最小值大于k
思路:我们先用ST表处理出最大值与最小值,然后用双指针从前往后扫描L,假如某个区间[L-R]满足条件,那么[L-R+1],[L-R+2]…[L-n]都会满足条件,所以答案res += n - r + 1即可,由于L从前往后,所以子数组不会重复

#include<iostream>
using namespace std;
#define inf 0x3f3f3f3f
#define IO ios::sync_with_stdio(false)
#define bug cout << "-----\n"
typedef long long ll;
int Mod = 1000000007;
const int N = 100010;
const int M = 500010;
int n;
int logn[N],f1[N][20],f2[N][20];
void init() {
	logn[0] = 0;
	logn[1] = 0;
	logn[2] = 1;
	for(int i=3;i<=n;i++)
		logn[i] = logn[i/2]+1;
}
void GetSt() {
	for(int i=1;i<=logn[n];i++) {
		for(int j=1;j+(1 << i)-1<=n;j++) {
			f1[j][i] = max(f1[j][i-1],f1[j+(1 << i-1)][i-1]);  
			f2[j][i] = min(f2[j][i-1],f2[j+(1 << i-1)][i-1]);        
		}
	}
}
int findMin(int l,int r) {
	int x = logn[r - l + 1];//区间长度!!!!!
	return min(f2[l][x],f2[r - (1 << x) + 1][x]);
}
int findMax(int l,int r) {
	int x = logn[r - l + 1];
	return max(f1[l][x],f1[r - (1 << x) + 1][x]);
}
int main() {
	int m,i,j,k;
	cin >> n >> m;
	init();
	for(i=1;i<=n;i++){
		cin >> f1[i][0];
		f2[i][0] = f1[i][0];
	}
	GetSt();
	while(m--) {
		ll res = 0;
		cin >> k;
		int l = 1,r = 1;
		while(l<=r&&r<=n) {
			if(findMax(l,r) - findMin(l,r) > k) {
				res += n - r + 1;
				l ++;
			}
			else {
				r ++;
			}
			if(l == r)
				r ++;
		}
		cout << res << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ST7789是一种高度集成的驱动芯片,专为TFT LCD显示屏设计。它具有低功耗、高效率和可靠性的特点,是许多电子设备中广泛采用的芯片之一。 ST7789芯片具有384×240分辨率,支持SPI接口通信,包括CLK、MISO、MOSI和CS等引脚,可以通过SPI接口与主控器进行通信。该芯片还内置有GRAM(图形显示存储器),可以存储图像数据。ST7789还支持16位和18位的RGB接口,以及多种显示模式,如横竖屏切换、颜色反转、亮度调节等功能。 该芯片还具有多达8种不同的显示模式,包括RD、WR、RS、RESET和CS信号,用于控制屏幕的刷新、写入、读取、复位和片选等操作。此外,ST7789还支持电源管理和休眠模式,可以在不需要显示时节省能量。 在使用ST7789芯片时,需要按照其产品手册中的规范进行引脚接线和相关时序设置。此外,还需要了解其指令集和寄存器配置,以便正确地控制显示屏的显示。 总之,ST7789是一款功能强大的驱动芯片,适用于各种TFT LCD显示屏,并且具有低功耗、高效率和可靠性等优点。 ### 回答2: ST7789是一款RGB TFT LCD驱动芯片,具有高分辨率、高亮度、高对比度和快速响应时间等特点。它广泛应用于移动设备、智能家居、汽车电子和嵌入式系统等领域。 ST7789芯片采用SPI接口,可支持最高480x320分辨率显示。通过在数据手册中查阅,我们可以了解到ST7789的引脚功能和电气特性。数据手册中还包含有关ST7789配置、初始化和操作的详细信息。 在ST7789的数据手册中,我们可以找到以下重要信息: - 芯片引脚定义:数据手册详细介绍了芯片的引脚功能和连接方式,包括电源引脚、SPI接口引脚和显示控制引脚等。这些信息对于正确接线和连接其他外围设备至关重要。 - 电气特性:数据手册提供了芯片工作电压和电流的参数范围,以及输入和输出信号电平范围。这些信息对于电源设计和信号处理非常重要,帮助确保芯片在规定的工作条件下正常运行。 - 寄存器配置:数据手册详细说明了ST7789芯片内部的寄存器及其相应的设置。这些寄存器可以用于选择显示模式、调整亮度和对比度、设置图像方向和颜色等。确保正确配置寄存器可实现所需的显示效果。 - 基本操作:数据手册提供了对ST7789进行复位、初始化和写入指令的操作说明。这些操作步骤可帮助开发人员快速上手并正确使用芯片。 总之,ST7789的数据手册提供了关于芯片的详细技术规格和使用说明。通过仔细阅读和理解数据手册,开发人员可以更好地了解ST7789的特性和使用方法,并能够在设计和开发中充分发挥其功能。 ### 回答3: ST7789是一款高性能的液晶显示控制器芯片,用于驱动彩色液晶显示屏。它采用了SPI接口进行数据传输,支持262K色显示和分辨率为240x320像素的屏幕。 ST7789芯片的主要特点有:功耗低,响应速度快,高可靠性,内部集成了多达12位的A/D转换器,可以实现高精度的颜色显示。此外,ST7789还支持垂直滚动显示、硬件窗口裁剪、硬件画线和亮度调节等功能,使得显现效果更加清晰和细腻。 ST7789芯片具有多种功耗模式,可以根据不同的使用场景选择合适的模式以达到节能的目的。同时,它还支持部分像素填充和图像旋转功能,方便用户进行图形、文本和图像的显示。 ST7789的数据手册提供了详细的技术规格和使用指南,包括芯片引脚的定义、电气特性、功能描述、寄存器配置等信息。通过研究和理解数据手册,开发者可以更加深入地了解ST7789芯片的工作原理和功能,从而更好地进行开发和设计。 总而言之,ST7789是一款功能强大的液晶显示控制器芯片,具有高性能、低功耗和丰富的功能特点。通过仔细研读相关的数据手册,可以更好地利用ST7789芯片进行液晶显示屏的驱动和应用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值