区间最大值,$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. Scrapy爬虫入门系列2 示例教程

    本来想爬下http://www.alexa.com/topsites/countries/CN 总排名的,但是收费了 只爬了50条数据: response.xpath('//div[@class=&q ...

  2. 基于EasyDarwin云视频平台的幼儿园视频直播(手机直播/微信直播)解决方案

    一.方案介绍 1.1.方案背景 在2016年10月25日至28日的安博会上,我们看到了不少的幼教平台厂商,我们注意到大部分的幼教平台,为了追求极佳的用户体验,在微信或者APP端能够做到极快的打开速度, ...

  3. file descriptor 0 1 2 一切皆文件 stdout stderr stdin /dev/null 沉默是金 pipes

    $>emtry_or_create_a_file.f $ll>>append_a_file.f standard output input error $ls -l /usr/bin ...

  4. 配置hadoop用户SSH无密码登陆 的2种方式 落脚点是 可以ssh免密进入的主机名写入动作发出主机的 known_hosts,而被无密进入主机的authorized_keys文件 免密登录

    cat /proc/versionLinux version 3.10.0-327.el7.x86_64 (builder@kbuilder.dev.centos.org) (gcc version ...

  5. 使用JavaScript获取浏览器UserAgent

    可以在浏览器地址栏输入about:version来查看UserAgent等信息 但是在Win10系统,本人亲测,IE和Edge用这样的方式都获取不到信息 在我惯用的QQ浏览器上倒是可以获取到 为了能方 ...

  6. ADFS 2016 – Cannot add/update Relying Parties from the GUI from metadata files “Method not found”

    UPDATE: The following update is fixing this issue: Cumulative Update for Windows 10 Version 1607 and ...

  7. 2018年东北农业大学春季校赛 B wyh的矩阵【规律】

    题目链接 https://www.nowcoder.com/acm/contest/93/B 思路 先加入 中间的那行 和中间的那列 再减去 最中间那个数 因为它 加了两次 然后逐行往下加 会发现是一 ...

  8. @GetMapping和@PostMapping接收参数的格式

    一.1.使用@Controller 注解,在对应的方法上,视图解析器可以解析return 的jsp,html页面,并且跳转到相应页面 若返回json等内容到页面,则需要加@ResponseBody注解 ...

  9. HDU5877 Weak Pair dfs + 线段树/树状数组 + 离散化

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5877 题意: weak pair的要求: 1.u是v的祖先(注意不一定是父亲) 2.val[u]*va ...

  10. linux系统配置之服务程序的开机自启动(centos)

    CentOS安装好apache.mysql等服务器程序后,并没有设置成开机自动启动的,为避免重启后还要手动开启web等服务器,还是做下设置好,其实设置很简单,用chkconfig命令就行了. 例如,要 ...