区间最大值,$O(nlogn)$ 预处理,$O(1)$ 查询,不能动态修改。在查询次数M显著大于元素数量N的时候看得出差距。

令 $f[i][j]$ 表示 $[i,i+2^j-1]$ 的最大值。

显然, $f[i][0]=a[i]$ 。

根据定义式,写出状态转移方程: $f[i][j]=max(f[i][j-1],f[i+2^{j-1}][j-1])$ 。

我们可以这么理解:将区间 $[i,i+2^j-1]$ 分成相同的两部分

中点即为 $(i+(i+2^j-1))/2=i+2^{j-1}-1/2$

所以 $[i,i+2^j-1]$ 可以分成 $[i,i+2^{j-1}-1]$ 和 $[i+2^j,i+2^j-1]$

对于每个询问 $[x,y]$ ,我们把它分成两部分 $f[x][s],f[y-2^s+1][s]$

其中 $s=log_2(y-x+1)$ ,虽然这两个区间有重叠,但是重叠不会影响区间的最大值

#include <bits/stdc++.h>
using namespace std;
#define ll long long const int MAXLOGN=;
const int MAXN=;
int a[MAXN+],f[MAXN+][MAXLOGN+1],Logn[MAXN+]; inline int read() {
char c=getchar();
int x=,f=;
while(c<''||c>'') {
if(c=='-')
f=-;
c=getchar();
}
while(c>=''&&c<='') {
x=x*+c-'';
c=getchar();
}
return x*f;
} void init() {
Logn[]=;
Logn[]=;
for(int i=; i<=MAXN; i++) {
Logn[i]=Logn[i/]+;
}
}
int main() {
init();
int n=read(),m=read();
for(int i=; i<=n; i++)
f[i][]=read();
for(int j=; j<=MAXLOGN; j++)
for(int i=; i+(<<j)-<=n; i++)
f[i][j]=max(f[i][j-],f[i+(<<(j-))][j-]);
for(int i=; i<=m; i++) {
int x=read(),y=read();
int s=Logn[y-x+];
printf("%d\n",max(f[x][s],f[y-(<<s)+][s]));
}
return ;
}

二维:

#include<bits/stdc++.h>
using namespace std;
#define MAXN 501
int n,m;
int rec[MAXN][MAXN];
char dp[MAXN][MAXN][][];
char dp1[MAXN][MAXN][][];
inline int maxm(int a,int b,int c,int d) {
if(a<b)
a=b;
if(a<c)
a=c;
if(a<d)
a=d;
return a;
}
inline int minm(int a,int b,int c,int d) {
if(b<a)
a=b;
if(c<a)
a=c;
if(d<a)
a=d;
return a;
}
void st() {
for(int k=; (<<k)<=n; k++)
for(int l=; (<<l)<=m; l++)
for(int i=; i+(<<k)-<=n; i++)
for(int j=; j+(<<l)-<=m; j++) {
if(!k&&!l) {
dp1[i][j][k][l]=dp[i][j][k][l]=rec[i][j];
} else if(k==) {
dp[i][j][k][l]=max(dp[i][j][k][l-],dp[i][j+(<<(l-))][k][l-]);
dp1[i][j][k][l]=min(dp1[i][j][k][l-],dp1[i][j+(<<(l-))][k][l-]);
} else if(l==) {
dp[i][j][k][l]=max(dp[i][j][k-][l],dp[i+(<<(k-))][j][k-][l]);
dp1[i][j][k][l]=min(dp1[i][j][k-][l],dp1[i+(<<(k-))][j][k-][l]);
} else {
dp[i][j][k][l]=maxm(dp[i][j][k-][l-],dp[i+(<<(k-))][j][k-][l-],
dp[i][j+(<<(l-))][k-][l-],dp[i+(<<(k-))][j+(<<(l-))][k-][l-]);
dp1[i][j][k][l]=minm(dp1[i][j][k-][l-],dp1[i+(<<(k-))][j][k-][l-],
dp1[i][j+(<<(l-))][k-][l-],dp1[i+(<<(k-))][j+(<<(l-))][k-][l-]);
}
//printf("dp[%d][%d][%d][%d]=%d\n",i,j,k,l,dp[i][j][k][l]);
}
}
int rmq2dmax(int x,int y,int x1,int y1) {
int k=;
while((x1-x+)>=(<<k))
k++;
k--;
int l=;
while((y1-y+)>=(<<l))
l++;
l--;
return maxm(dp[x][y][k][l],dp[x1-(<<k)+][y][k][l],
dp[x][y1-(<<l)+][k][l],dp[x1-(<<k)+][y1-(<<l)+][k][l]);
} int rmq2dmin(int x,int y,int x1,int y1) {
int k=;
while((x1-x+)>=(<<k))
k++;
k--;
int l=;
while((y1-y+)>=(<<l))
l++;
l--;
return minm(dp1[x][y][k][l],dp1[x1-(<<k)+][y][k][l],
dp1[x][y1-(<<l)+][k][l],dp1[x1-(<<k)+][y1-(<<l)+][k][l]);
} int main() {
int g;
scanf("%d%d%d",&n,&m,&g);
for(int i=; i<=n; i++) {
for(int j=; j<=m; j++) {
scanf("%d",&rec[i][j]);
}
}
st();
for(int l=min(n,m); l; l--) {
for(int i=; i<=n; i++) {
if(i+l->n)
break;
for(int j=; j<=m; j++) {
if(j+l->m)
break;
int t=rmq2dmax(i,j,i+l-,j+l-)-rmq2dmin(i,j,i+l-,j+l-);
if(t<=g){
printf("%d\n",l);
exit();
}
}
}
}
}

模板 - 数据结构 - ST表 + 二维ST表的更多相关文章

  1. [模板]二维ST表

    考试yy二维ST表失败导致爆零. 其实和一维的ST表很像... 也是设$f[i][j][p][q]$为以$(i, j)$为左上角,长为$2^p$,宽为$2^q$的矩形的最大值. 算法流程是先把每一行都 ...

  2. BZOJ3577:玩手机(最大流,二维ST表)

    Description 现在有一堆手机放在坐标网格里面(坐标从1开始),坐标(i,j)的格子有s_(i,j)个手机. 玩手机当然需要有信号,不过这里的手机与基站与我们不太一样.基站分为两种:发送站和接 ...

  3. BZOJ1047[HAOI2007]理想的正方形——二维ST表

    题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入 第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非 ...

  4. 【CodeForces】713 D. Animals and Puzzle 动态规划+二维ST表

    [题目]D. Animals and Puzzle [题意]给定n*m的01矩阵,Q次询问某个子矩阵内的最大正方形全1子矩阵边长.n,m<=1000,Q<=10^6. [算法]动态规划DP ...

  5. 【洛谷 P2216】 [HAOI2007]理想的正方形(二维ST表)

    题目链接 做出二维\(ST\)表,然后\(O(n^2)\)扫一遍就好了. #include <cstdio> #include <cstring> #include <a ...

  6. Codeforces 713D Animals and Puzzle(二维ST表+二分答案)

    题目链接 Animals and Puzzle 题意  给出一个1e3 * 1e3的01矩阵,给出t个询问,每个询问形如x1,y1,x2,y2 你需要回答在以$(x1, y1)$为左上角,$(x1, ...

  7. [HNOI2007] 理想正方形 二维ST表

    题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一行为3个整数,分别表示a,b,n的值 第二行至 ...

  8. 二维 ST POJ 2019

    题目大意:给你一个n*n的矩阵,每次给你一个点(x,y),以其为左上角,宽度为b的矩阵中最小的数值和最大数值的差是多少?  一共k个询问. 思路:简单的二维st. 定义dp(i,j,k,L)表示以(i ...

  9. 数据结构:二维ST表

    POJ2019 我们其实是很有必要把ST算法拓展到二维的,因为二维的RMQ问题还是不少的 int N,B,K; ]; int val[maxn][maxn]; ][]; ][]; 这里的N是方阵的长宽 ...

随机推荐

  1. 每天一点儿Java--list

    import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; /** * ...

  2. php把时间存入数据库为年月日时分秒类型

    时间用now() $sql1 = "insert into registerip (name,logintime,ip,url) values ('1211121',now(),'127.0 ...

  3. 搭建React Native开发环境

    搭建React Native开发环境 本文档是Mac下搭建的环境,针对的目标平台不同,以及开发 iOS 和 Android 的不同,环境搭建也有差异. Github地址:https://github. ...

  4. WEBRTC开发入门

    WEBRTC "WebRTC,名称源自网页实时通信(Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的技术,是谷歌2010年以6 ...

  5. 判断一个IP地址是否是本局域网内地址

    //        /// <summary>        /// 判断一个IP地址是否是本局域网内地址,是返回true 否则返回false,        /// </summa ...

  6. 编译性语言&amp;解释性语言

    计算机是不能理解高级语言.当然也就不能直接执行高级语言了.计算机仅仅能直接理解机器语言,所以不论什么语言,都必须将其翻译成机器语言.不论什么编程语言编写的程序归根究竟都是由底层机器的机器代码(01序列 ...

  7. spring cloud - 注册中心

    服务注册与发现 这里我们会用到Spring Cloud Netflix,该项目是Spring Cloud的子项目之一,主要内容是对Netflix公司一系列开源产品的包装,它为Spring Boot应用 ...

  8. jquery特效(4)—轮播图②(定时自动轮播)

    周末出去逛完街,就回公司好好地研究代码了,也算是把定时自动轮播程序写出来了,特意说明一下,这次的轮播图是在昨天随笔中jquery特效(3)—轮播图①(手动点击轮播)的基础上写出来的,也就是本次随笔展示 ...

  9. git解决冲突方式

    Git解决冲突 安装beyond compare 4 2.配置git对比工具 #difftool 配置 git config --global diff.tool bc4 git config --g ...

  10. 截图工具,更改系统默认快捷键,系统配置实用程序,以管理员身份运行cmd(win7)

    截图工具: 开始--附件--右键发送到桌面快捷方式---桌面截图工具右键属性--快捷方式 更改系统默认快捷键: 控制面板--外观和个性化--调整屏幕分辨率--高级设置---英特尔图形和媒体控制面板-- ...