Codeforces 713D Animals and Puzzle(二维ST表+二分答案)
题目链接 Animals and Puzzle
题意 给出一个1e3 * 1e3的01矩阵,给出t个询问,每个询问形如x1,y1,x2,y2
你需要回答在以$(x1, y1)$为左上角,$(x1, y2)$为右下角的子矩阵中,最大的全1正方形的边长。
首先考虑DP预处理。
$f[i][j]$表示以$f[i][j]$为右下角的最大的全1正方形的边长。
则$f[i][j] = min(f[i - 1][j], f[i][j - 1], f[i - 1][j - 1]) + 1$
我们对$f[i][j]$构建一张二维ST表,使我们能在$O(1)$的时间复杂度内求出$f[i][j](x1 <= i <= x2, y1 <= j <= y2)$
但是这样直接查询$f[i][j]$的最大值$(x1 <= i <= x2, y1 <= j <= y2)$是不行的。
因为查询到的最大全1子正方形并不一定都在以$(x1, y1)$为左上角,$(x1, y2)$为右下角的子矩阵中。
所以我们需要另外想办法。
我们可以判断一个答案x是否存在,先求出合法的$f[i][j] >= x$的范围,
也就是说如果找到$f[i][j] >= x$了,这个找到的全1子正方形一定都在以$(x1, y1)$为左上角,$(x1, y2)$为右下角的子矩阵中。
显然x是单调的,所以我们可以二分答案。
时间复杂度$O(nmlognm + t)$
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i) const int N = 1e3 + 3;
const int M = 10; int f[N][N][M][M], lg[N];
int n, m, x, q; void ST(){
rep(i, 2, 1e3 + 1) lg[i] = lg[i >> 1] + 1;
rep(i, 1, n){
for (int k = 1; (1 << k) <= m; ++k){
rep(j, 1, m - (1 << k) + 1){
f[i][j][0][k] = max(f[i][j][0][k - 1], f[i][j + (1 << (k - 1))][0][k - 1]);
}
}
} for (int k1 = 1; (1 << k1) <= n; ++k1){
rep(i, 1, n - (1 << k1) + 1){
for (int k2 = 0; (1 << k2) <= m; ++k2){
rep(j, 1, m - (1 << k2) + 1){
f[i][j][k1][k2] = max(f[i][j][k1 - 1][k2], f[i + (1 << (k1 - 1))][j][k1 - 1][k2]);
}
}
}
}
} int query(int x1, int y1, int x2, int y2){
int k1 = lg[x2 - x1 + 1], k2 = lg[y2 - y1 + 1];
x2 = x2 - (1 << k1) + 1;
y2 = y2 - (1 << k2) + 1;
return max(max(f[x1][y1][k1][k2], f[x1][y2][k1][k2]), max(f[x2][y1][k1][k2], f[x2][y2][k1][k2]));
} int main(){ freopen("1.txt", "r", stdin);
freopen("2.txt", "w", stdout); scanf("%d%d", &n, &m); rep(i, 1, n){
rep(j, 1, m){
int x;
scanf("%d", &x);
if (x) f[i][j][0][0] = min(f[i - 1][j - 1][0][0],
min(f[i - 1][j][0][0], f[i][j - 1][0][0])) + 1;
else f[i][j][0][0] = 0;
}
} ST();
scanf("%d", &q);
while (q--){
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
int l = 0, r = min(x2 - x1, y2 - y1) + 1, ans = 0;
while (l <= r){
int mid = (l + r) >> 1;
if (query(x1 + mid - 1, y1 + mid - 1, x2, y2) >= mid) l = mid + 1, ans = mid;
else r = mid - 1;
} printf("%d\n", ans);
} return 0;
}
Codeforces 713D Animals and Puzzle(二维ST表+二分答案)的更多相关文章
- Codeforces Round #371 (Div. 1) D - Animals and Puzzle 二维ST表 + 二分
D - Animals and Puzzle #include<bits/stdc++.h> #define LL long long #define fi first #define s ...
- 【CodeForces】713 D. Animals and Puzzle 动态规划+二维ST表
[题目]D. Animals and Puzzle [题意]给定n*m的01矩阵,Q次询问某个子矩阵内的最大正方形全1子矩阵边长.n,m<=1000,Q<=10^6. [算法]动态规划DP ...
- BZOJ3577:玩手机(最大流,二维ST表)
Description 现在有一堆手机放在坐标网格里面(坐标从1开始),坐标(i,j)的格子有s_(i,j)个手机. 玩手机当然需要有信号,不过这里的手机与基站与我们不太一样.基站分为两种:发送站和接 ...
- BZOJ1047[HAOI2007]理想的正方形——二维ST表
题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入 第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非 ...
- 【洛谷 P2216】 [HAOI2007]理想的正方形(二维ST表)
题目链接 做出二维\(ST\)表,然后\(O(n^2)\)扫一遍就好了. #include <cstdio> #include <cstring> #include <a ...
- [模板]二维ST表
考试yy二维ST表失败导致爆零. 其实和一维的ST表很像... 也是设$f[i][j][p][q]$为以$(i, j)$为左上角,长为$2^p$,宽为$2^q$的矩形的最大值. 算法流程是先把每一行都 ...
- [HNOI2007] 理想正方形 二维ST表
题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一行为3个整数,分别表示a,b,n的值 第二行至 ...
- Codeforces Round #371 (Div. 1) D. Animals and Puzzle 二维倍增
D. Animals and Puzzle 题目连接: http://codeforces.com/contest/713/problem/D Description Owl Sonya gave a ...
- [总结] 二维ST表及其优化
二维 \(\mathcal{ST}\) 表,可以解决二维 \(\mathcal{RMQ}\) 问题.这里不能带修改,如果要修改,就需要二维线段树解决了. 上一道例题吧 ZOJ2859 类比一维 \(\ ...
随机推荐
- spring-security中的csrf防御机制(跨域请求伪造)
什么是csrf? csrf又称跨域请求伪造,攻击方通过伪造用户请求访问受信任站点.CSRF这种攻击方式在2000年已经被国外的安全人员提出,但在国内,直到06年才开始被关注,08年,国内外的多个大型社 ...
- C++ static关键字
一.面向过程中的static 1.修饰全局变量(静态全局变量) (1)静态全局变量在全局数据区分配内存: (2)未经初始化的静态全局变量会被程序自动初始化为0: (3)静态全局变量在申明它的整个文件是 ...
- 第2节 azkaban调度:17、azkaban的两个服务模式的安装
2.3.3.azkaban两个服务模式安装 1.确认所需软件: Azkaban Web服务安装包 azkaban-web-server-0.1.0-SNAPSHOT.tar.gz Azkaban执行服 ...
- Java——舞动的排序
一.冒泡排序: http://v.youku.com/v_show/id_XMzMyOTAyMzQ0.html //冒泡排序 public class Bubbling { public static ...
- Linux网卡设置为网桥模式
Linux网卡设置为网桥模式 1. 添加网卡,并修改相关配置文件 1.1虚拟机添加网卡,并配置相关文件 如:eth2为新添加网卡 cd /etc/sysconfig/network-script ...
- C# 使用Epplus导出Excel [2]:导出动态列数据
C# 使用Epplus导出Excel [1]:导出固定列数据 C# 使用Epplus导出Excel [2]:导出动态列数据 C# 使用Epplus导出Excel [3]:合并列连续相同数据 C# 使用 ...
- Linux实现删除撤回的方法。
RM命令改造 vim /etc/bashrc 在文件的最前端添加如下代码 #修改rm命令 alias rm=delete #命令别名,通过delete来实现rm改为mv alias r=de ...
- Python之路-迭代器 生成器 推导式
迭代器 可迭代对象 遵守可迭代协议的就是可迭代对象,例如:字符串,list dic tuple set都是可迭代对象 或者说,能被for循环的都是可迭代对象 或者说,具有对象.__iter__方法的都 ...
- Django 千锋培训的学习笔记(1)
Django 千锋培训读书笔记 https://www.bilibili.com/video/av17879644/?p=1 切换到创建项目的目录 cd C:\Users\admin\Desktop\ ...
- Hive 启动报错,需先启动元数据
Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: Unable ...