题目

这个题的算法核心就是求出以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. [网页游戏开发]容器的使用及自定义Tab,RadioGroup,List,ViewStack

    Morn里面,容器和其他普通组件不同,无需皮肤,所以也不能从组件树种拖动创建(Tab,RadioGroup例外),只能转换而来 Morn的容器组件主要有Box,Container,Panel,Tab, ...

  2. Hadoop源代码分析(完整版)

    Hadoop源代码分析(一) 关键字: 分布式云计算 Google的核心竞争技术是它的计算平台.Google的大牛们用了下面5篇文章,介绍了它们的计算设施. GoogleCluster:http:// ...

  3. bash shell和进程

    1 exec builtin 不创建子shell,在原进程的上启动新的脚本,但是它会把老shell的环境清理掉,所以,它从原shell中什么也不继承,在一个干净的环境中执行新的脚本.执行完之后退出当前 ...

  4. Delphi之萝莉调教篇

    本文纯属技术交流.如果各位看官想与小生一起探讨萝莉的问题的话...PM我吧 关于Delphi的萝莉调教技术,很久以前就有大牛做过了...其实技术早掌握了只是觉得太无聊~估计大家也都会于是就没有写~既然 ...

  5. mini_magick

    https://github.com/minimagick/minimagick class  https://www.rubydoc.info/github/minimagick/minimagic ...

  6. bzoj5328: [Sdoi2018]物理实验

    果然我还是太菜了,爆了一天才过....隔壁肉丝都不知道喊了多少句哎╮(╯▽╰)╭我又A了什么傻逼题(然鹅就是wf和国集的题QWQ) 其实这个题就是个裸题,但是我就是不会... 这个题第一步就是明显的旋 ...

  7. dedecms列表页如何调用栏目关键词和描述

    问:dedecms列表页如何调用栏目关键词和描述 答:有人问起dedecms列表页如何调用栏目关键词和描述.解答如下: 自己实验了下总结方法如下:(以下方法使用于栏目封面和列表和内容页,其他的地方没有 ...

  8. codeforces A. Kitahara Haruki's Gift 解题报告

    题目链接:http://codeforces.com/problemset/problem/433/A 题目意思:给定 n 个只由100和200组成的数,问能不能分成均等的两份. 题目其实不难,要考虑 ...

  9. PHP加密方式。 base!base!base!

    PHP中的加密方式有如下几种 1. MD5加密 string md5 ( string $str [, bool $raw_output = false ] ) 参数 str  --  原始字符串. ...

  10. wukong引擎源码分析之搜索——docid有序的数组里二分归并求交集,如果用跳表的话,在插入索引时会更快

    searcher.Search(types.SearchRequest{Text: "百度中国"}) // 查找满足搜索条件的文档,此函数线程安全 func (engine *En ...