二维st表

article/2025/6/30 4:19:32

摘要

我们知道一维的st表在经过预处理后可以在O(1)时间内查询任意区间的极值,虽然其是离线算法,但胜在代码短小易写。而在二维RMQ(区间最值查询)问题中,我们依然可以采用st算法解决问题,只不过我们需要从一维拓展到二维,当然适用范围依然是离线。二维st表仍然是用倍增思想,如果理解了一维的st表,那么对于二维的也不难理解。

问题描述

给定一个n* n的矩阵以及一个整数b和k,共有k次询问,每次询问给出边长为b的子矩阵的左上角的行和列(r,c),请回答该子矩阵内的最大值和最小值的差是多少。

算法思路

变量定义:
st[r][c][k]存放以(r , c)为左上角的边长为 2 k 2^k 2k个元素的矩阵的最大值。
a[n][n]用来存放矩阵中的元素。

查询操作:
假设我们的st表已经更新完毕,此时st[r][c][k]中存放的是以(r , c)为左上角的边长为 2 k 2^k 2k 的矩阵内的最大值,那么对于一个查询(a , b , c) 即查询以(a , b)为左上角,边长为 c 的矩阵内的最大值该如何处理呢?
显然和一维一样,由于我们的st表中存放的区间长度是2的次方项,因此如果边长并不恰好是2的次方项,那么就无法通过一次访问st表求得,需要通过几个重叠区间得出结果。在二维RMQ中,就体现为将一个大矩阵查询分为4个小矩阵查询。
下面我们具体来讲一下如何划分查询区间。假设我们要查询的是以(a,b)为左上角,边长为 c 的矩阵内的最大值,那么假设 k = l o g 2 c k = log_2^c k=log2c 向下取整,那么显然st[a][b][k]是一个如下图(a)中显示的一个小矩阵。

在这里插入图片描述

那么显而易见,st[a][b+c-(1<<k)+1][k]正如(b)中的蓝色矩形一样覆盖了以右上角为顶点的矩阵。同理,我们共需要四个矩形来覆盖整个大矩形,如(c)所示。因此对于任意边长的正方形,我们都可以计算出其覆盖面积的最大值。因为求极值操作是允许区间重叠的( [1 , 10] 的最大值可以由[1 , 6] 的最大值和[2 , 10]的最大值得出 ),因此上述划分方法虽有区间重叠,但对最终答案没有影响(求和则不行)。
总结起来,若设最终要求的答案为ans,则:

令t1 = st[a][b][c];
令t2 = st[a][b+c-(1<<k)+1][c];
令t3 = st[a+c-(1<<k)+1][b][c];
令t4 = st[a+c-(1<<k)+1][b+c-(1<<k)+1][c];
ans = max{t1 , t2 , t3 , t4};

因此我们得证了,利用上述定义的st表,确实可以在常数时间内求出目标矩阵的最大值。

更新st表(预处理)
我们在一开始就提到过,st表是离线算法, 即不支持修改操作,因此以此预处理之后便只能进行查询。预处理时间复杂度为 O ( N 2 l o g 2 N ) O(N^2log_2N) O(N2log2N)。预处理用到了动态规划的思想。
更新也是同样的道理,更新一个大矩形,需要用到4个小矩形。状态转移方程如下:

st[i][j][k] = Max( st[i][j][k-1] , st[i+(1<<k-1)][j][k-1] , st[i][j+(1<<k-1)][k-1] , st[i+(1<<k-1)][j+(1<<k-1)][k-1]);

为什么这个式子成立呢?如果从式子上看, 2 k − 1 + 2 k − 1 = 2 k 2^{k-1} + 2^{k-1} = 2^k 2k1+2k1=2k,因此俩个小区间可以更新一个大区间,拓展到二维上呢,就是4个小矩阵更新一个大矩阵。如果用图来描述,就如(d)所示,四个小矩形构成一个大矩形,而大矩形的边长是小矩形的2倍。于是我们就可以通过四个小矩阵的值来更新大矩阵的值。
在这里插入图片描述

例题 HAOI2007理想的正方形

解题思路:
本题就是一个二维RMQ问题的裸题,和上述模型不同的是,其是一个长a宽b的矩形,而非正方形。不管是矩形还是正方形,我们的更新和查询都是划分为4个子矩阵来更新或查询,因此只需对代码稍作改变即可,基本没太大变化,预处理都是 O ( N 2 l o g N ) O(N^2logN) O(N2logN),查询也都是O(1)。

代码示例:

#include<cstdio>
const int N = 1010;
int a[N][N],n,m,len,Log[N];
int st[3][N][N][15];//0最小,1最大值 
int max(int a,int b,int c,int d){int mx = a;if(mx < b) mx = b;if(mx < c) mx = c;if(mx < d) mx = d;return mx;
}
int min(int a,int b,int c,int d){int mi = a;if(mi > b) mi = b;if(mi > c) mi = c;if(mi > d) mi = d;return mi;
}
void init(){for(int i = 2;i < N;i++) Log[i] = Log[i/2]+1;for(int i = 1;i <= n;i++)for(int j = 1;j <= m;j++) st[0][i][j][0] = st[1][i][j][0] = a[i][j];for(int k = 1;k <= 12;k++){for(int i = 1;i + (1<<k)-1 <= n;i++){for(int j = 1;j + (1<<k)-1 <= m;j++){int t1 = st[0][i][j][k-1];int t2 = st[0][i+(1<<(k-1))][j][k-1];int t3 = st[0][i][j+(1<<(k-1))][k-1];int t4 = st[0][i+(1<<k-1)][j+(1<<k-1)][k-1];st[0][i][j][k] = min(t1,t2,t3,t4);t1 = st[1][i][j][k-1];t2 = st[1][i+(1<<(k-1))][j][k-1];t3 = st[1][i][j+(1<<(k-1))][k-1];t4 = st[1][i+(1<<k-1)][j+(1<<k-1)][k-1];st[1][i][j][k] = max(t1,t2,t3,t4);}}}
}
int ask(int r,int c,int len){int k = Log[len];int t1 = st[0][r][c][k];int t2 = st[0][r+len-(1<<k)][c][k];int t3 = st[0][r][c+len-(1<<k)][k];int t4 = st[0][r+len-(1<<k)][c+len-(1<<k)][k];int mi = min(t1,t2,t3,t4);t1 = st[1][r][c][k];t2 = st[1][r+len-(1<<k)][c][k];t3 = st[1][r][c+len-(1<<k)][k];t4 = st[1][r+len-(1<<k)][c+len-(1<<k)][k];int mx = max(t1,t2,t3,t4);//printf("%d %d\n",mx,mi);return mx - mi;
}
int main(){scanf("%d%d%d",&n,&m,&len);for(int i = 1;i <= n;i++)for(int j = 1;j <= m;j++) scanf("%d",&a[i][j]);init();int ans = 0x3f3f3f3f;for(int i = 1;i <= n-len+1;i++){for(int j = 1;j <= m-len+1;j++){int tmp = ask(i,j,len);ans = ans < tmp?ans:tmp;}}printf("%d\n",ans);return 0;
}

结束语

大家可以发现我们的二维st表建立在正方形矩阵查询的基础上的,因此st表仅三个维度,即st[r][c][k]代表以(r , c) 为左上角的边长为 2 k 2^k 2k的矩阵的极值;但如果所给矩阵以及所求矩阵并不是正方形而是普通矩形,那就要增加一个维度,即st[r][c][k1][k2]表示以(r,c)为左上角,长为 2 k 1 2^{k1} 2k1高为 2 k 2 2^{k2} 2k2的矩阵的极值,其更新方法与本文所介绍的类似,都是通过4个子矩阵来更新,查询也是通过4个子矩阵来查询最终答案。


http://chatgpt.dhexx.cn/article/GZxaGyew.shtml

相关文章

【C#】读取txt、csv等二维表

程序要读文件&#xff0c;在实战中主要还是以二维表为主&#xff0c;类似下图这种&#xff1a; 基本上除了掌握《【C#】txt的读写》&#xff08;点击打开链接&#xff09;的文件流的读写&#xff0c;还需要与《【C#】利用正则表达式判断输入是否为纯数字、容器类》&#xff08;…

MySQL一维表变二维表_二维表转换一维表,三种方法一网打尽!

小伙伴们&#xff0c;早上好&#xff01;新的一天又开始了&#xff0c;学习的脚步不能停。 今天向大家分享二维表格转一维表的三种方法&#xff0c;分别用到函数、数据透视表和VBA代码。三种方法各有利弊&#xff0c;表亲可以自行选择。 如下图&#xff0c;A1:E5是数据源&#…

给二维表添加时间序列索引

一&#xff0c;读取数据 import pandas as pd open_dataspd.read_csv(./data328/open328.csv,headerNone) open_datas.head()(可以看到索引为数字) 二&#xff0c;创建时间序列 import pandas as pd open_dataspd.read_csv(./data328/open328.csv,headerNone) open_datas.h…

excel二维表转化为一维表

1、什么是二维表和一维表 二维表即表中有两个维度&#xff0c;纵向维度的哪列值唯一 一维表即只有列名一个维度 2、 添加工具并转换 我们需要添加【数据透视表和数据透视图向导】功能来完成&#xff0c;如果已经设置可以忽略这步 文件--选项--自定义功能区--不在功能区的命令…

Excel如何快速将一维表转为二维表

如下图左侧是某公司销售一维表&#xff0c;现在想要将其快速转换成右侧这种二维表。 选中姓名列所有数据区域&#xff0c;然后点击下图选项&#xff08;Excel工具箱&#xff0c;具体安装方法百度即可&#xff0c;本文不作过多叙述&#xff09; 选择【随机重复】&#xff0c;然后…

【Python】Pandas DataFrame 一维表二维表的转换

目录 一、stack & unstackunstack 将一维表转换为二维表stack 将二维表转换为一维表 二、pivot & meltpivot 将一维表转换为二维表melt将二维表转换为一维表 Tips 用pandas处理数据&#xff0c;我们经常获取到的是从数据库或者excel中获取的一维表。而常常需要重排&…

Excel:一维表和二维表 互转

一、一维表转二维表 数据源&#xff1a; 一份流水账式的值班表&#xff0c;为了便于打印张贴&#xff0c;现在需要使其变成这样的样式&#xff1a; 也就是从一维表变成传说中的二维表。 1、新建查询 依次单击【数据】→【新建查询】 →【从文件】→【从工作簿】 找到存放的工作…

mysql 二维表 查询_二维报表数据表设计

报表原型: 这里随便挑了一个二维报表 二维报表设计分析: 上面的报表原型行和列都有数据项,我们可以根据地理位置的经纬度定坐标点的思想来进行设计 这里使用列行来表示 c1r1表示第一列第一行 c1r2表示第一列第二行 ..... c2r1表示第二列第一行 c2r2表示第二 报表原型: 这里随便…

MySQL一维表变二维表_一维表转化为二维表,你会吗?

原标题&#xff1a;一维表转化为二维表&#xff0c;你会吗&#xff1f; 在产品的一些销售数据处理中&#xff0c;我们经常看到这样的一维表数据: 我们在进行数据的统计分析时&#xff0c;需要用这样的一维表作为数据源&#xff0c;所以正常情况下我们会用一维表的格式进行数据的…

python一维列表变二维列表_使用Python轻松应对一维表与二维表相互转换

数据分析时,同事经常给你一份二维表,是不是分分钟有想哭的冲动,一大堆的东西在一块,怎么透视?想要做进一步分析,也是特别麻烦。今天给你一种方便的方法。 一、入门版 先来看看可能要处理的文件是什么样的? 看看,别提多闹心了。当然我们不可能一开始就处理这么复杂的样…

Python实现一维表与二维表之间的相互转化

对已有数据表进行一维和二维之间的转化&#xff1a; import pandas as pd# 读入数据&#xff1a; df pd.read_excel(2dims.xls,Sheet1) df df的结构为&#xff1a; 如上图所示df是一个二维表。 # 将二维数据表转化为一维数据表&#xff1a; new_data df.set_index(地区) #…

java 二维表格_实现二维表

create or replace function getGoodsMsgForProtocol( str_in in varchar2,str_classId in varchar2)--分类字 return varchar2 is str_list varchar2(4000) default null;--连接后字符串 str_int number(2) default 0; begin for x in ( select goods.goodsname,goods.specs f…

二维表 转一维表 mysql_Excel二维表转换成一维表(2种方法)

今天大年初四&#xff0c;春节假期还剩三天了&#xff0c;每逢佳节胖三斤&#xff0c;亲们可要注意控制饮食了&#xff0c;要不然春节后无脸见人哟。闲话少说&#xff0c;今日分享如下。 在做数据处理的时候&#xff0c;有的时候为了处理方便我们需要将二维的数据表处理成一维的…

【一起学Rust | 进阶篇 | Grid库】二维表数据结构——Grid

文章目录 前言一、Grid安装和引入二、使用1. 运行官方案例2. Grid宏3. new4. init5. from_vec6. get7. get_mut8. size9. rows10. cols11. is_empty12. clear13. iter14. iter_mut15. iter_col16. iter_col_mut17. iter_row18. iter_row_mut19. push_row20. push_col21. pop_ro…

数据库中的二维表—巧借Excel

一维表和二维表的区别 一维表也常称为流水线表格&#xff0c;它和二维表做出的数据透视表最大的区别在于"行总计"。判断数据是一维表格还是二维表格的一个最简单的办法&#xff0c;就是看其列的内容--每一列是否是一个独立的参数。如果每一列都是独立的参数那就是一维…

倾向得分加权匹配分析方法的R实现

1.1 PSW Package 简介 PSW : Propensity Score Weighting Methods for Dichotomous Treatments. 该包由Huzhang Mao 和LiangLi两位作者贡献&#xff0c;首次发布于2017年10月&#xff1b;该包主要运用倾向得分加权分析方法实现因果效应的推断&#xff1b;主要由5个函数模块构成…

python倾向匹配得分_手把手教你做倾向评分匹配 -PSM

原标题:手把手教你做倾向评分匹配 -PSM 本文首发于“百味科研芝士”微信公众号,转载请注明:百味科研芝士,Focus科研人的百味需求。 各位科研芝士的朋友大家好,今天和大家分享一下新的知识点—PSM,或许大家早已听过这个名词了,或许你对它还是半知半解,不过没关系,希望…

回归问题的置信区间AUC_互助问答第193期:倾向得分匹配法与面板数据问题

问题一&#xff1a;老师您好&#xff01;我的问题是倾向得分匹配法之前要对匹配变量进行选择&#xff0c;我看见连玉君老师的一篇文章中主要是对处理变量和匹配变量做logit回归&#xff0c;然后根据准R方和AUC值判断&#xff0c;两者越大越好&#xff0c;通常来说AUC应该大于0.…

倾向值匹配法的概述和应用+倾向值分析:统计方法与应用

倾向值匹配法的概述和应用 一、因果推论理论概述 1.在应用倾向值匹配法进行因果推断时需要注意后续的检验理论&#xff0c;否则容易妄议因果。 2.什么是倾向值匹配法&#xff1f; 将各个手册单元多维度的信息&#xff0c;使用统计方法简化成一维的数值&#xff0c;是为倾向值…

因果推断(二)倾向匹配得分(PSM)

因果推断&#xff08;二&#xff09;倾向匹配得分&#xff08;PSM&#xff09; 前文介绍了如何通过合成控制法构造相似的对照组&#xff0c;除此之外&#xff0c;也可以根据倾向匹配得分&#xff08;PSM&#xff09;进行构造&#xff0c;即为每一个试验组样本在对照组中找对与…