题目链接:BZOJ - 1047

题目分析

使用单调队列在 O(n^2) 的时间内求出每个 n * n 正方形的最大值,最小值。然后就可以直接统计答案了。

横向有 a 个单调队列(代码中是 Q[1] 到 Q[a] ),维护每行当前枚举区间的单调队列。

纵向一个单调队列(代码中是 Q[0] ),求出当前枚举区间的每行的单调队列后,就得到了每行的这个区间的最小值(最大值),就相当于一个长度为行数的数组,然后纵向做单调队列,求出的就是正方形的最值了。

代码

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>using namespace std;const int MaxN = 1000 + 5, INF = 999999999;int a, b, n, Ans;
int Map[MaxN][MaxN], Q[MaxN][MaxN], F[MaxN], Head[MaxN], Tail[MaxN], Min[MaxN][MaxN], Max[MaxN][MaxN];
//Q[0]是纵向的单调队列 inline int gmin(int a, int b) {return a < b ? a : b;}
inline int gmax(int a, int b) {return a > b ? a : b;}void Get_Min()
{for (int i = 1; i <= a; ++i) {Head[i] = 1;Tail[i] = 0;}for (int i = 1; i <= b; ++i) {for (int j = 1; j <= a; ++j) {if (i > n && Head[j] <= Tail[j] && Q[j][Head[j]] == i - n) ++Head[j];while (Head[j] <= Tail[j] && Map[j][i] < Map[j][Q[j][Tail[j]]]) --Tail[j];Q[j][++Tail[j]] = i; }   if (i >= n) {Head[0] = 1; Tail[0] = 0;for (int j = 1; j <= a; ++j){F[j] = Map[j][Q[j][Head[j]]];if (j > n && Head[0] <= Tail[0] && Q[0][Head[0]] == j - n) ++Head[0];while (Head[0] <= Tail[0] && F[j] < F[Q[0][Tail[0]]]) --Tail[0];Q[0][++Tail[0]] = j;if (j >= n) Min[j][i] = F[Q[0][Head[0]]]; }}}
}void Get_Max()
{for (int i = 1; i <= a; ++i) {Head[i] = 1;Tail[i] = 0;}for (int i = 1; i <= b; ++i) {for (int j = 1; j <= a; ++j) {if (i > n && Head[j] <= Tail[j] && Q[j][Head[j]] == i - n) ++Head[j];while (Head[j] <= Tail[j] && Map[j][i] > Map[j][Q[j][Tail[j]]]) --Tail[j];Q[j][++Tail[j]] = i; }if (i >= n) {Head[0] = 1; Tail[0] = 0;for (int j = 1; j <= a; ++j){F[j] = Map[j][Q[j][Head[j]]];if (j > n && Head[0] <= Tail[0] && Q[0][Head[0]] == j - n) ++Head[0];while (Head[0] <= Tail[0] && F[j] > F[Q[0][Tail[0]]]) --Tail[0];Q[0][++Tail[0]] = j;if (j >= n) Max[j][i] = F[Q[0][Head[0]]]; }}}
}int main()
{scanf("%d%d%d", &a, &b, &n);for (int i = 1; i <= a; ++i) for (int j = 1; j <= b; ++j) scanf("%d", &Map[i][j]);Get_Min();Get_Max();Ans = INF;for (int i = n; i <= a; ++i) for (int j = n; j <= b; ++j) Ans = gmin(Ans, Max[i][j] - Min[i][j]);printf("%d\n", Ans);return 0;
}

  

转载于:https://www.cnblogs.com/JoeFan/p/4319732.html

[BZOJ 1047] [HAOI2007] 理想的正方形 【单调队列】相关推荐

  1. BZOJ 1047: [HAOI2007]理想的正方形 单调队列瞎搞

    题意很简明吧? 枚举的矩形下边界和右端点即右下角,来确定矩形位置: 每一个纵列开一个单调队列,记录从 i-n+1 行到 i 行每列的最大值和最小值,矩形下边界向下推移的时候维护一下: 然后在记录的每一 ...

  2. bzoj 1047: [HAOI2007]理想的正方形

    1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3324  Solved: 1828 [Submit][ ...

  3. [HAOI2007] 理想的正方形 (单调队列)

    题目链接 Solution MD,经过这道题,算是掌握单调队列了... 可以先预处理出点 \((i,j)\) 往上 \(n\) 的最大值和最小值. 然后再横着做一遍单调队列即可. Code #incl ...

  4. bzoj1047 [HAOI2007]理想的正方形 单调队列

    这种在矩形里面找矩形有固定的套路,不是容斥就是左右上下延伸,这个题就是向左向右延伸.. 然后手玩优化发现邻位转移比暴力要好一些,可以用splay统计,但复杂度不对 然后由于每一行互不影响于是可以单行同 ...

  5. BZOJ 1047 理想的正方形(单调队列)

    刚开始用二维RMQ直接给超内存了... 用单调队列可以做到O(n^2)的复杂度.具体是先把每行用单调队列处理一下.再把处理后的用列单调队列处理下. # include <cstdio> # ...

  6. P2216 理想的正方形 单调队列 (二维)

    题目链接:https://www.luogu.org/problem/P2216 题意:求给定n*m的矩形中所有k*k的正方形块中最大值最小值之差(极差)最小 哇,大神的思路真的很帅 单调队列对每一行 ...

  7. bzoj1047/luogu2216 理想的正方形 (单调队列)

    开b组单调队列,分别维护此时某一列中的最大/最小值 然后我每次把它们的头取出来,塞到维护行的单调队列里,就是n*n的最大/最小值 1 #include<bits/stdc++.h> 2 # ...

  8. AcWing1091.理想的正方形(单调队列DP)

    题目传送门 有一个 a×b 的整数组成的矩阵,现请你从中找出一个 n×n 的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入格式 第一行为三个整数,分别表示 a,b,n 的值: 第二行至 ...

  9. [HAOI2007] 理想的正方形

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

最新文章

  1. java练习:模拟试下你斗地主的洗牌、发牌、看牌功能
  2. 惊闻VeryCD的电驴下载部分即将关闭
  3. 打算把我的视频工具整合一下
  4. Nginx 负载均衡配置和策略
  5. Quartz 之入门示例
  6. hal库开启中断关中断_STM32对HAL库的定时器中断
  7. 安装EXSI遇到No Network Adapters的解决方案
  8. 软件测试--selenium安装使用
  9. 抄底公式---预测黑马
  10. Docker详解(十)——Docker容器CPU资源限额配置
  11. 慵懒中长大的人,只会挨生活留下的耳光
  12. 《Go程序设计语言》- 第13章:低级编程
  13. Sublime Text 2 注册码/破解方法【蕃薯耀】
  14. ubuntu下网易云的特别替代品-VS code cloudmusic插件
  15. wx2540h配置教程_H3C WX2540H系列无线控制器 安装指导-6W101
  16. S5p4418平台AP6212 WIFI稳定性的解决过程
  17. 泰凌微8258入门教程 环境篇②——Telink IDE开发环境搭建
  18. 失传千年AE特效真经(三)
  19. android 获取设备的mac地址,Android编程获取设备MAC地址的实现方法
  20. Godot Shader:无需建模用一张图片在Godot中生成一座山

热门文章

  1. 《尼山萨满》项目美术亲述游戏创作过程
  2. LNMP单机高并发的简单优化
  3. final,finally,finaliz的区别(Java)
  4. 前端性能优化(PC版)
  5. 如何恢复XP系统中原来的Administrator用户
  6. Linux Shell 通配符、元字符、转义符使用实例介绍
  7. 网络编程第三讲UDP编写
  8. 2017校招真题在线编程-幸运的袋子
  9. UVa 10642 - Can You Solve It?
  10. 服务器强迫患者 ;软件试用狂人