当前位置: 首页 > news >正文

20250913 P11503 [NordicOI 2018] Nordic Camping

P11503 [NordicOI 2018] Nordic Camping

二分 + DS 妙题

思路

首先我们可以发现。若有一个点 \((x, y)\),则我们可以通过二分求出以 \((x, y)\) 为左上角的最大空正方形的边长(记为 \(b[i][j]\)),check 就是判断以 \((x, y)\) 为左上角的边长为 \(mid\) 的正方形是否为空,其单调性在于我们的条件使得边长更大的正方形完全包括边长更小的正方形,若边长更小的正方形不为空则边长更大的正方形一定不为空。并且,某个作为答案的正方形一定是以某个点为左上角的最大空正方形。

然后,一种方案是。我们分析以 \((x, y)\) 为左上角的最大空正方形对答案的贡献,发现应该把整个正方形中的所有点的答案都和当前正方形的面积取 \(\max\),于是树套树即可。

第二种方案是,我们考虑对于每一个询问去求解答案。此时我们又可以二分答案。Check 判断以 \((x, y)\) 为右下角的边长为 \(mid\) 正方形中的 \(\max b[i][j]\) 是否大于等于 \(mid\),起单调性与上类似,同样是考虑问题之间是包含的。 二维 ST 表维护即可。

Code

#include<bits/stdc++.h>using namespace std;const int N = 2e3 + 5, L = 12;int n, m, q;
int a[N][N], sum[N][N], f[N << 1][N << 1][L], lg[N]; inline int S(int x1, int y1, int x2, int y2) {return sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1];
}inline int Query(int x1, int y1, int x2, int y2) {int k = lg[x2 - x1 + 1], a = 1 << k;return max({f[x1][y1][k], f[x2 - a + 1][y1][k], f[x1][y2 - a + 1][k], f[x2 - a + 1][y2 - a + 1][k]});
}int main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);cin >> n >> m;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {char ch;cin >> ch;a[i][j] = ch == '#';sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + a[i][j];			}}for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {int l = 0, r = min(n - i + 1, m - j + 1);while (l < r) {int mid = l + r + 1 >> 1;S(i, j, i + mid - 1, j + mid - 1) ? r = mid - 1 : l = mid;}f[i + N][j + N][0] = (!a[i][j]) * l;}}for (int i = 2; i <= max(n, m); i++) {lg[i] = lg[i >> 1] + 1;}for (int i = 1; i < L; i++) {int a = 1 << i, b = 1 << i - 1;for (int j = 1; j + a - 1 <= n + N; j++) {for (int k = 1; k + a - 1 <= m + N; k++) {f[j][k][i] = max({f[j][k][i - 1], f[j + b][k][i - 1], f[j][k + b][i - 1], f[j + b][k + b][i - 1]}); }}}cin >> q;for (int x, y; q--; ) {cin >> x >> y;x += N, y += N;int l = 0, r = max(n, m);while (l < r) {int mid = l + r + 1 >> 1;Query(max(1, x - mid + 1), max(1, y - mid + 1), x, y) >= mid ? l = mid : r = mid - 1;	}cout << l * l << '\n';}return 0;
}
http://www.wxhsa.cn/company.asp?id=3773

相关文章:

  • Dify实战训练营(基础班)(全免费值得收藏)
  • C 语言的历史和版本
  • PostgreSQL 上的向量搜索实践
  • 【数据结构——图与邻接矩阵】 - 实践
  • (读书笔记)平衡掌控者
  • 带头结点的单链表删除指定位置结点
  • 《文字、语言与数字的奇妙联结》读后感,大公司内部编码规范,本学期编码遵守规范
  • [HTTP/Spring] RestTemplate : Spring的HTTP网络请求框架
  • 深入解析:Linux使用-MySQL的使用
  • 博客园-我的博客-的皮肤更换
  • Apache Commons Math3 使用指南:强大的Java数学库 - 教程
  • HarmonyOS图形处理:Canvas绘制与动画开发实战
  • script setup 在 Vue 3 中的核心作用及具体实现方式
  • 0voice-1.4.1-cmake
  • test test test
  • 容器化改造基本原理
  • Blogroll 友链
  • Java 字节码与 ASM 框架实战解析
  • 计算机大数据毕业设计选题:基于Spark+hadoop的全球香水市场趋势分析系统 - 详解
  • Dos的常用命令
  • 持续集成自动化CI/CD
  • Lightroom Classic 2025(LRC 2025)安装教程(附直接安装包下载)+入门操作指南
  • 2025/09/14 【二叉树11】完全二叉树的节点个数
  • 8888
  • 接口限流代码 - 实践
  • OutGuess 安装与问题排查指南(Kali Linux 环境)
  • 拓展操作码举例
  • TryHackMe | Cicada-3301 Vol:1
  • 完整教程:Word添加图/表题注
  • [MCP][01]简介与概念