题目

这个题的算法核心就是求出以i,j为左上角,边长为n的矩阵中最小值和最大值。最小和最大值的求法类似。

单调队列做法:

以最小值为例:

q1[i][j]表示第i行上,从j列开始的n列的最小值。
$q1[i][j]=min(x[i][j],x[i][j+1],...,x[i][j+n-1])$
$q1[i][1]=min(x[i][1],x[i][2],...,x[i][n])$
$q1[i][2]=min(x[i][2],x[i][3],...,x[i][n+1])$
类似滑动窗口,因此直接枚举行,对于每一行单调队列处理即可。

q2[i][j]表示以第i行第j列为左上角的边长为n的矩阵的最小值
$q2[i][j]=min(q1[i][j],q1[i+1][j],...,q1[i+n-1][j])$
$q2[1][j]=min(q1[1][j],q1[2][j],...,q1[n][j])$
$q2[2][j]=min(q1[2][j],q1[3][j],...,q2[n+1][j])$
显然又可以用单调队列处理。总时间复杂度$O(n^2)$

(额外)更简短的做法(二维ST表,$O(n^2\;log\;n)$):

(由于要求的是正方形,因此可以$O(n^2\;log\;n)$,一般应该是$O({(n\;log\;n)}^2)$)

用f[i][j][k]来表示横纵坐标分别为i,j开始到i+2^k-1,j+2^k-1的整个矩阵(正方形)中的最大值

https://www.luogu.org/wiki/show?name=%E9%A2%98%E8%A7%A3+P2216

笔记:

1.这道题一开始想到了可能跟单调队列有关系,但是并没有想清楚。想了很久后,把q1和q2的关系式列了出来,一切就明朗了。

2.求最小值的单调队列队首(l)最小,队尾(r)最大,l<r。求最大值的单调队列队首(l)最大,队尾(r)最小,l<r。

求最小值的单调队列
2 3 5 4 6 1
1. 2
2. 2 3
3. 2 3 5
4. 2 3 4
5. 2 3 4 6
6. 1

3.单调队列的调试还算方便,只需要开着对单调队列的变量查看,观察内部元素是否正常就行了。

 #include<cstdio>
#define min(a,b) ((a)>(b)?(b):(a))
typedef long long LL;
LL a,b,n;
LL x[][];
LL q1min[][],q1max[][],q2min[][],q2max[][];
LL tmpmin[],tmpmax[],lmin,rmin,lmax,rmax,anss=0x3f3f3f3f3f3f3f3f;
int main()
{
LL i,j;
scanf("%lld%lld%lld",&a,&b,&n);
for(i=;i<=a;i++)
for(j=;j<=b;j++)
scanf("%lld",&x[i][j]);
for(i=;i<=a;i++)
{
lmin=rmin=lmax=rmax=;
for(j=;j<=n;j++)
{
while(rmin>lmin&&x[i][tmpmin[rmin-]]>=x[i][j]) rmin--;
tmpmin[rmin++]=j;
while(rmax>lmax&&x[i][tmpmax[rmax-]]<=x[i][j]) rmax--;
tmpmax[rmax++]=j;
}
q1min[i][]=x[i][tmpmin[lmin]];
q1max[i][]=x[i][tmpmax[lmax]];
for(j=n+;j<=b;j++)
{
if(rmin>lmin&&tmpmin[lmin]<=j-n) lmin++;
if(rmax>lmax&&tmpmax[lmax]<=j-n) lmax++;
while(rmin>lmin&&x[i][tmpmin[rmin-]]>=x[i][j]) rmin--;
tmpmin[rmin++]=j;
while(rmax>lmax&&x[i][tmpmax[rmax-]]<=x[i][j]) rmax--;
tmpmax[rmax++]=j;
q1min[i][j-n+]=x[i][tmpmin[lmin]];
q1max[i][j-n+]=x[i][tmpmax[lmax]];
}
}
for(i=;i<=b;i++)
{
lmin=rmin=lmax=rmax=;
for(j=;j<=n;j++)
{
while(rmin>lmin&&q1min[tmpmin[rmin-]][i]>=q1min[j][i]) rmin--;
tmpmin[rmin++]=j;
while(rmax>lmax&&q1max[tmpmax[rmax-]][i]<=q1max[j][i]) rmax--;
tmpmax[rmax++]=j;
}
q2min[][i]=q1min[tmpmin[lmin]][i];
q2max[][i]=q1max[tmpmax[lmax]][i];
for(j=n+;j<=a;j++)
{
if(rmin>lmin&&tmpmin[lmin]<=j-n) lmin++;
if(rmax>lmax&&tmpmax[lmax]<=j-n) lmax++;
while(rmin>lmin&&q1min[tmpmin[rmin-]][i]>=q1min[j][i]) rmin--;
tmpmin[rmin++]=j;
while(rmax>lmax&&q1max[tmpmax[rmax-]][i]<=q1max[j][i]) rmax--;
tmpmax[rmax++]=j;
q2min[j-n+][i]=q1min[tmpmin[lmin]][i];
q2max[j-n+][i]=q1max[tmpmax[lmax]][i];
}
}
for(i=;i<=a-n+;i++)
for(j=;j<=b-n+;j++)
anss=min(anss,q2max[i][j]-q2min[i][j]);
printf("%lld",anss);
return ;
}

洛谷 P2216 [HAOI2007]理想的正方形 || 二维RMQ的单调队列的更多相关文章

  1. 洛谷 P2216 [HAOI2007]理想的正方形

    P2216 [HAOI2007]理想的正方形 题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一 ...

  2. 洛谷P2216: [HAOI2007]理想的正方形 单调队列优化DP

    洛谷P2216 )逼着自己写DP 题意: 给定一个带有数字的矩阵,找出一个大小为n*n的矩阵,这个矩阵中最大值减最小值最小. 思路: 先处理出每一行每个格子到前面n个格子中的最大值和最小值.然后对每一 ...

  3. 【bzoj1047】[HAOI2007]理想的正方形 二维RMQ

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

  4. 洛谷P2216 HAOI2007 理想的正方形 (单调队列)

    题目就是要求在n*m的矩形中找出一个k*k的正方形(理想正方形),使得这个正方形内最值之差最小(就是要维护最大值和最小值),显然我们可以用单调队列维护. 但是二维平面上单调队列怎么用? 我们先对行处理 ...

  5. 【DP】【单调队列】洛谷 P2216 [HAOI2007]理想的正方形 题解

        算是单调队列的复习吧,不是很难 题目描述 有一个$a\times b$的整数组成的矩阵,现请你从中找出一个$n\times n$的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入 ...

  6. [洛谷P2216][HAOI2007]理想的正方形

    题目大意:有一个$a\times b$的矩阵,求一个$n\times n$的矩阵,使该区域中的极差最小. 题解:二维$ST$表,每一个点试一下是不是左上角就行了 卡点:1.用了一份考试时候写的二维$S ...

  7. BZOJ1047或洛谷2216 [HAOI2007]理想的正方形

    BZOJ原题链接 洛谷原题链接 显然可以用数据结构或\(ST\)表或单调队列来维护最值. 这里采用单调队列来维护. 先用单调队列维护每一行的最大值和最小值,区间长为正方形长度. 再用单调队列维护之前维 ...

  8. 洛谷 P2216 [HAOI2007]理想正方形

    洛谷 巨说这是一道单调队列好题,但是我并不是用单调队列做的诶. 如果往最暴力的方向去想,肯定是\(n^3\)的\(dp\)了. \(f[i][j][k]\)代表当前正方形的左上角定点是\((i,j)\ ...

  9. 洛谷 2216 [HAOI2007]理想的正方形

    题目戳这里 一句话题意 给你一个a×b的矩形,求一个n×n的子矩阵,矩阵里面的最大值和最小值之差最小. Solution 这个题目许多大佬都是单调队列,但是我不是很会,只好用了比较傻逼的方法: 首先我 ...

随机推荐

  1. Mac使用小结

    1.修改pip的镜像地址及更新pip https://www.cnblogs.com/techroad4ca/p/5922389.html 2.更新python的库,比如更新six sudo pip ...

  2. MapReduce算法形式二:去重(shuffle)

    案例二:去重(shuffle/HashSet等方法)shuffle主要针对的是key去重HashSet主要针对values去重

  3. 您可能试图从server上的安全浏览器訪问此站点。请启用脚本然后又一次载入此页。

    您可能试图从server上的安全浏览器訪问此站点.请启用脚本然后又一次载入此页.         我使用域Admin组的账户登入SharePoint2010的server,打开SharePoint首页 ...

  4. 基于Ubuntu 14.04 LTS编译Android4.4.2源码

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/gobitan/article/details/24367439 基于Ubuntu 14.04 LTS ...

  5. POJ2942 Knights of the Round Table 点双连通分量 二分图判定

    题目大意 有N个骑士,给出某些骑士之间的仇恨关系,每次开会时会选一些骑士开,骑士们会围坐在一个圆桌旁.一次会议能够顺利举行,要满足两个条件:1.任意相互憎恨的两个骑士不能相邻.2.开会人数为大于2的奇 ...

  6. DataSnap Mobile Client Tutorial

    One of my customers was having some difficulty following the DataSnap tutorial which can be found he ...

  7. css的书写规范,有哪些注意点

    一.框架为先,细节次之. 先写一些浮动,然后高与宽,然后再是细节方面的书写. 比如写一个浮动容器的样式,我们应该先让这个容器的框架被渲染出来,让大家看到基本的 网站框架.然后再再去渲染容器里面的内容. ...

  8. html5--6-8 CSS选择器5

    html5--6-8 CSS选择器5 实例 <!DOCTYPE html> <html lang="zh-cn"> <head> <met ...

  9. VC++读写文件

    目录 第1章读写文件    1 1.1 API    1 1.2 低级IO    1 1.2.1 文件序号    1 1.2.2 文本文件与二进制文件    1 1.3 流IO    2 1.4 Un ...

  10. 礼物gift(DP)

    这道题的DP非常的有意思…… 一开始我们总是会以为这是一个背包问题,直接dp[0] = 0,dp[j] += dp[j-c[i]]进行转移.之后统计一下从dp[m-minn]~dp[m]的答案之和为结 ...