区间最大值,$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. 小白学开发(iOS)OC_ 字符串重组(2015-08-13)

    // //  main.m //  字符串重组 // //  Created by admin on 15/8/13. //  Copyright (c) 2015年 admin. All right ...

  2. You're trying to decode an invalid JSON String JSON返回有解析问题

    SpringMVC架构的web程序,通常用map返回消息在浏览器中显示,但是实际中报下列错误“”You're trying to decode an invalid JSON String“返回的字符 ...

  3. Chef vs Puppet vs Ansible vs Saltstack: Which Works Best For You?

    Ansible vs SaltStack 谁才是自动化运维好帮手? - CSDN博客 https://blog.csdn.net/a105421548/article/details/53558598 ...

  4. Markov and Chebyshev Inequalities and the Weak Law of Large Numbers

    https://www.math.wustl.edu/~russw/f10.math493/chebyshev.pdf http://www.tkiryl.com/Probability/Chapte ...

  5. DIV+CSS常见问题的14条原因分析

    当你在一个浏览器里面做好,在其他浏览器里面却完全不是那么回事情.  很多时候,我们就只是去修补下,或者利用各个浏览器对代码支持的不一致,进行针对各个浏览器进行不同的定义.  其实浏览器的不兼容,我们往 ...

  6. hibernate属性配置

    数据库中一个字段的默认值设为0,当用hibernate插入数据时,没有对该字段进行操作,结果该字段居然不是0,而是空.后来google了一下,发现应该在.hbm.xml文件中添加一些参数定义(示例中的 ...

  7. git使用笔记(四)错误报告 Git push rejected error: fatal: refusing to merge unrelated histories

    Reason: The reason is because I created repo in Github with initiated README.md file, and I tried to ...

  8. Android记录程序崩溃Log写入文件

    将导致程序崩溃的堆栈调用Log写入文件,便于收集bug.在调试安卓程序,由于某些原因调试时手机不能连接PC端,无法通过IDE查看程序崩溃的Log,希望log能够写入文件中,对于已经发布的App可以通过 ...

  9. codeforces B. George and Round 解题报告

    题目链接:http://codeforces.com/contest/387/problem/B 题目意思:给出1-n个问题,以及要满足是good rounde条件下这n个问题分别需要达到的compl ...

  10. [原创]java操作word(一)

    一. 需求背景 在做项目的过程中,经常会遇到要把数据库数据导出到Word文件中的需求,因为很多情况下,我们需要将数据导出到WORD中进行打印.此需求可以通过用程序填充数据到word模板中来实现.所谓模 ...