[HAOI2007]理想的正方形

题目描述

有一个\(a*b\)的整数组成的矩阵,现请你从中找出一个\(n*n\)的正方形区域,使得该区域所有数中的最大值和最小值的差最小。

输入输出格式

输入格式:

第一行为3个整数,分别表示\(a,b,n\)的值

第二行至第\(a+1\)行每行为\(b\)个非负整数,表示矩阵中相应位置上的数。每行相邻两数之间用一空格分隔。

输出格式:

仅一个整数,为\(a*b\)矩阵中所有\(n*n\)正方形区域中的最大整数和最小整数的差值”的最小值。

输入输出样例

输入样例#1:

5 4 2
1 2 5 6
0 17 16 0
16 17 2 1
2 10 2 1
1 2 2 2

输出样例#1:

1

说明

问题规模

(1)矩阵中的所有数都不超过\(1,000,000,000\)

(2)\(20\%\)的数据\(2<=a,b<=100,n<=a,n<=b,n<=10\)

(3)\(100\%\)的数据\(2<=a,b<=1000,n<=a,n<=b,n<=100\)

题解

刚学的二维\(ST\)表,和一维的大同小异。

\(mx[k][i][j]\)表示以\((i,j)\)作为左上角,边长为\(2^k\)的正方形内的最大值。

转移:

$mx[k][i][j]=max(max(mx[k-1][i][j],mx[k-1][i][j+(1<<(k-1))]),max(mx[k-1][i+(1<<(k-1))][j],mx[k-1][i+(1<<(k-1))][j+(1<<(k-1))])); $

最小值也是一样。

最后\(N^2\)枚举左上角端点统计答案。

code:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#define ll long long
#define R register
#define N 1005
using namespace std;
template<typename T>inline void read(T &a){
char c=getchar();T x=0,f=1;
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
a=f*x;
}
int a,b,n,x,maxans,minans,ans=0x7fffffffLL,mx[11][N][N],mi[11][N][N];
int main(){
read(a);read(b);read(n);
for(R int i=1;i<=a;i++)
for(R int j=1;j<=b;j++)
read(x),mi[0][i][j]=mx[0][i][j]=x;
for(R int k=1;(1<<k)<=n;k++)
for(R int i=1;i<=a-(1<<k)+1;i++)
for(R int j=1;j<=b-(1<<k)+1;j++)
mi[k][i][j]=min(min(mi[k-1][i][j],mi[k-1][i][j+(1<<(k-1))]),min(mi[k-1][i+(1<<(k-1))][j],mi[k-1][i+(1<<(k-1))][j+(1<<(k-1))])),
mx[k][i][j]=max(max(mx[k-1][i][j],mx[k-1][i][j+(1<<(k-1))]),max(mx[k-1][i+(1<<(k-1))][j],mx[k-1][i+(1<<(k-1))][j+(1<<(k-1))]));
R int k=(int)log2(n);
for(R int i=1;i<=a-n+1;i++){
for(R int j=1;j<=b-n+1;j++){
minans=0x7fffffff;maxans=-0x7fffffff;
maxans=max(max(mx[k][i][j],mx[k][i][j+n-(1<<k)]),max(mx[k][i+n-(1<<k)][j],mx[k][i+n-(1<<k)][j+n-(1<<k)]));
minans=min(min(mi[k][i][j],mi[k][i][j+n-(1<<k)]),min(mi[k][i+n-(1<<k)][j],mi[k][i+n-(1<<k)][j+n-(1<<k)]));
ans=min(maxans-minans,ans);
}
}
printf("%d\n",ans);
return 0;
}

【BZOJ1047】[HAOI2007]理想的正方形 (倍增ST表)的更多相关文章

  1. BZOJ1047: [HAOI2007]理想的正方形 [单调队列]

    1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2857  Solved: 1560[Submit][St ...

  2. bzoj千题计划215:bzoj1047: [HAOI2007]理想的正方形

    http://www.lydsy.com/JudgeOnline/problem.php?id=1047 先用单调队列求出每横着n个最大值 再在里面用单调队列求出每竖着n个的最大值 这样一个位置就代表 ...

  3. BZOJ1047[HAOI2007]理想的正方形——二维ST表

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

  4. [bzoj1047][HAOI2007]理想的正方形_动态规划_单调队列

    理想的正方形 bzoj-1047 HAOI-2007 题目大意:有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 注释:$2\le a, ...

  5. [Bzoj1047][HAOI2007]理想的正方形(ST表)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1047 题目虽然有一个n的限制,但求二维区间最值首先想到的还是RMQ,但是如果按照往常RM ...

  6. BZOJ1047: [HAOI2007]理想的正方形

    传送门 蛤省省选果然水啊,我这种蒟蒻都能一遍A. 横向纵向维护两个单调队列,做两次求最大和最小的,总复杂度$O(NM)$ 码农题,考察代码实现能力 //BZOJ 1047 //by Cydiater ...

  7. [BZOJ1047][HAOI2007]理想的正方形(RMQ+DP)

    题意 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 思路 RMQ求 再DP 代码 #include<cstdio> #i ...

  8. 【单调队列】bzoj1047 [HAOI2007]理想的正方形

    先把整个矩阵处理成b[n][m-K+1].c[n][m-K+1]大小的两个矩阵,分别存储每行每K个数中的最大.最小值,然后再通过b.c处理出d.e分别表示K*K大小的子矩阵中的最大.最小值即可.单调队 ...

  9. [BZOJ1047][HAOI2007]理想的正方形 二维单调队列

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1047 我们对每矩阵的一列维护一个大小为$n$的单调队列,队中元素为矩阵中元素.然后扫描每一 ...

  10. bzoj1047 [HAOI2007]理想的正方形——二维单调队列

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1047 就是先对行做一遍单调队列,再对那个结果按列做一遍单调队列即可. 代码如下: #incl ...

随机推荐

  1. PHP 乘法口诀表

    echo "乘法口诀表<br>"; for($i=1;$i<10;$i++) { for ($j = 1; $j <= $i; $j++) printf(& ...

  2. java Web servlet简介及其生命周期

    Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,主要功能在于交互式地浏览和修改数据,生成动态Web内容. 我们可 ...

  3. codeforce469DIV2——C. Zebras

    题意 0, 010, 01010 这一类的01交替且开头和结尾都为0的序列被称为zebra序列.给出一段01序列,尝试能否把他分为k个子序列使得每个子序列都是zebra序列. 分析 这个题应该算是水题 ...

  4. linux 压力测试工具 webbench

    webbench最多可以模拟3万个并发连接去测试网站的负载能力,个人感觉要比Apache自带的ab压力测试工具好,安装使用也特别方便. 1.适用系统:Linux 2.编译安装: 1. wget htt ...

  5. Python父类调用子类

    首先说明,上面的标题其实是不正确的,Python是一门解释型.动态数据类型的高级语言,运行时,动态判断调用对象,其实还是子类自己在调用自己的方法或属性. 举个例子(copy过来的):SocketSer ...

  6. WEB前端--JavaScript

    JavaScript JavaScript基础 一.JavaScript简介 JavaScript是一种嵌入到HTML文件中的描述性语言,由浏览器的解释器将其动态地处理成可执行的代码,能独立地完成与客 ...

  7. Django框架 之 ORM中介模型

    Django框架 之 ORM中介模型 中介模型 处理类似搭配 pizza 和 topping 这样简单的多对多关系时,使用标准的ManyToManyField  就可以了.但是,有时你可能需要关联数据 ...

  8. Working with WordprocessingML documents (Open XML SDK)

    Last modified: January 13, 2012 Applies to: Office 2013 | Open XML This section provides conceptual ...

  9. c#缓存介绍

    #缓存介绍(转) 本章导读 缓存主要是为了提高数据的读取速度.因为服务器和应用客户端之间存在着流量的瓶颈,所以读取大容量数据时,使用缓存来直接为客户端服务,可以减少客户端与服务器端的数据交互,从而大大 ...

  10. Android绘图之Matrix

    一.概述 1. 在Android中,如果你用Matrix进行过图像处理,那么一定知道Matrix这个类.Android中的Matrix是一个3 x 3的矩阵,其内容如下 2.Matrix的对图像的处理 ...