模板 - 数据结构 - ST表 + 二维ST表
区间最大值,$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表的更多相关文章
- [模板]二维ST表
考试yy二维ST表失败导致爆零. 其实和一维的ST表很像... 也是设$f[i][j][p][q]$为以$(i, j)$为左上角,长为$2^p$,宽为$2^q$的矩形的最大值. 算法流程是先把每一行都 ...
- BZOJ3577:玩手机(最大流,二维ST表)
Description 现在有一堆手机放在坐标网格里面(坐标从1开始),坐标(i,j)的格子有s_(i,j)个手机. 玩手机当然需要有信号,不过这里的手机与基站与我们不太一样.基站分为两种:发送站和接 ...
- BZOJ1047[HAOI2007]理想的正方形——二维ST表
题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入 第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非 ...
- 【CodeForces】713 D. Animals and Puzzle 动态规划+二维ST表
[题目]D. Animals and Puzzle [题意]给定n*m的01矩阵,Q次询问某个子矩阵内的最大正方形全1子矩阵边长.n,m<=1000,Q<=10^6. [算法]动态规划DP ...
- 【洛谷 P2216】 [HAOI2007]理想的正方形(二维ST表)
题目链接 做出二维\(ST\)表,然后\(O(n^2)\)扫一遍就好了. #include <cstdio> #include <cstring> #include <a ...
- Codeforces 713D Animals and Puzzle(二维ST表+二分答案)
题目链接 Animals and Puzzle 题意 给出一个1e3 * 1e3的01矩阵,给出t个询问,每个询问形如x1,y1,x2,y2 你需要回答在以$(x1, y1)$为左上角,$(x1, ...
- [HNOI2007] 理想正方形 二维ST表
题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一行为3个整数,分别表示a,b,n的值 第二行至 ...
- 二维 ST POJ 2019
题目大意:给你一个n*n的矩阵,每次给你一个点(x,y),以其为左上角,宽度为b的矩阵中最小的数值和最大数值的差是多少? 一共k个询问. 思路:简单的二维st. 定义dp(i,j,k,L)表示以(i ...
- 数据结构:二维ST表
POJ2019 我们其实是很有必要把ST算法拓展到二维的,因为二维的RMQ问题还是不少的 int N,B,K; ]; int val[maxn][maxn]; ][]; ][]; 这里的N是方阵的长宽 ...
随机推荐
- 02 http协议之方法与状态码
一:HTTP请求信息和响应信息的格式 请求: ()请求行 ()请求头信息 ()请求主体信息(可以没有) () 头信息结束后和主体信息之间要空一行 请求行又分3部分 请求方法 请求路径 所用的协议 请求 ...
- linux新建文件和文件夹命令
1.touch命令 touch命令用来修改文件的访问时间.修改时间.如果没有指定时间,则将文件时间属性改为当前时间. 当指定文件不存在,touch命令变为创建该文件. 语法: touch [-acm] ...
- MVC入门——列表页
创建控制器UserInfoController using System; using System.Collections.Generic; using System.Linq; using Sys ...
- leetcode题目解答报告(1)
Remove Element 题目: Given an array and a value, remove all instances of that value in place and retur ...
- Entity Framework(EF)(一)之database first
1.EF简介ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案.该框架曾经为.NET Framework的 ...
- 九度OJ 1118:数制转换 (进制转换)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3873 解决:1494 题目描述: 求任意两个不同进制非负整数的转换(2进制-16进制),所给整数在long所能表达的范围之内. 不 ...
- A桶中有多少水?
如果你能算出桶中有多少水,我便许你下山去玩.有一天,老和尚让小和尚将A桶的水挑到B桶去,可是小和尚却想下山玩,不愿意挑水,老和尚便说:”如果你能够根据我的提示算出A桶中有多少升水,我便许你下山去玩.” ...
- 关于indexOf的使用
今天项目中出现一个bug,在筛选数据的时候出现了冗余数据,查找发现在indexOf方法判断的时候找到了问题的所在. package demo; public class test { public s ...
- java to Json or Json to JavaBean
今天练习,放这里,以后再补充 这里使用的jar包是 net.sf.json.JSONObject package yh.test.t1118; import net.sf.json.JSONArray ...
- ibatis 优点,未完版
iBatis是Apache的一个开源项目,一个O/R Mapping(???)解决方案,iBatis最大的特点就是小巧,上手很快,如果不需要太多复杂的功能,ibatis是能满足你得要求又足够灵活的最简 ...