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

题解:P13933 [蓝桥杯 2022 省 Java B] 最大子矩阵

发现标签是单调队列,我也不会单调队列,所以写 K-Dtree。

正文

一句话题意(迫真)

求所有满足矩形区域内最大值和最小值的差不大于 \(lim\) 的矩形区域的面积的最大值。

解析

那么思路就很清晰了。

我们发现 \(n\) 很小,所以直接两层循环枚举矩形的高,而 \(m\),也就是宽,结合简单的最优性策略,我们可以用双指针一遍扫过去。

那么枚举矩形就做到了 \(O(n^2m)\) 的复杂度。

然后就是如何得到矩形区域的最大最小值$。

这个很显然吧,直接 K-Dtree 维护矩形最大最小值就可以做了。
点数最多是 \(nm\) 的,这一步的复杂度可以很容易做到 \(O(\log nm)\)

然后就可以拼起来了,总复杂度 \(O(n^2m \log nm)\),思路很简单,码略长。

代码

// code by 樓影沫瞬_Hz17
#include <bits/stdc++.h>
using namespace std;#define getc() getchar_unlocked()
#define putc(a) putchar_unlocked(a)
#define en_ putc('\n')
#define e_ putc(' ')using pii = pair<int, int>;template<class T> inline T in() { T n = 0; char p = getc();while (p < '-') p = getc();bool f = p == '-' ? p = getc() : 0;do n = n * 10 + (p ^ 48), p = getc();while (isdigit(p));return f ? -n : n;return n;
}
template<class T> inline T in(T &a) { return a = in<T>(); }template<class T> inline void out(T n) {if(n < 0) putc('-'), n = -n;if(n > 9) out(n / 10);putc(n % 10 + '0');
}template<class T1, class T2> T1 max(T1 a, T2 b) { return a > b ? a : a = b;}
template<class T1, class T2> T1 min(T1 a, T2 b) { return a < b ? a : a = b;}const int N = 1e5 + 10;struct pot { // 完全就是 K-Dtree 的模板,有什么不会的自行 oi-wikiint x[2], val;
} p[N * 2];struct node {int mi[2], mx[2], val[2]; // 需要维护最大最小值int l, r;pot p;
} t[N * 2];inline void up(int u) {int l = t[u].l, r = t[u].r;for(int i : {0, 1}) {t[u].mi[i] = t[u].mx[i] = t[u].p.x[i];t[u].val[0] = t[u].val[1] = t[u].p.val;if(l) {t[u].mi[i] = min(t[u].mi[i], t[l].mi[i]);t[u].mx[i] = max(t[u].mx[i], t[l].mx[i]);t[u].val[0] = min(t[u].val[0], t[l].val[0]);t[u].val[1] = max(t[u].val[1], t[l].val[1]);}if(r) {t[u].mi[i] = min(t[u].mi[i], t[r].mi[i]);t[u].mx[i] = max(t[u].mx[i], t[r].mx[i]);t[u].val[0] = min(t[u].val[0], t[r].val[0]);t[u].val[1] = max(t[u].val[1], t[r].val[1]);}}
}int cnt;inline void build(int&u, int l, int r, int wd) { // 建树 (我在写什么注释啊啊啊,完全不知道应该写什么注释)if(l > r) return;int m = (l + r) >> 1;nth_element(p + l, p + m, p + r + 1, [&](pot a, pot b) { return a.x[wd] < b.x[wd]; });t[u = ++ cnt].p = p[m];build(t[u].l, l, m - 1, wd ^ 1);build(t[u].r, m + 1, r, wd ^ 1);up(u);
}inline bool inr(node p, int mi[2], int ma[2]) { // in rangereturn p.mi[0] >= mi[0] and p.mx[0] <= ma[0] and p.mi[1] >= mi[1] and p.mx[1] <= ma[1]; 
}inline bool outr(node p, int mi[2], int mx[2]) { // out of rangereturn p.mi[0] > mx[0] || p.mx[0] < mi[0] || p.mi[1] > mx[1] || p.mx[1] < mi[1];
}inline bool inr(pot p, int mi[2], int ma[2]) { // in rangereturn p.x[0] <= ma[0] and p.x[0] >= mi[0] and p.x[1] <= ma[1] and p.x[1] >= mi[1];
}inline pii query(int u, int mi[2], int ma[2]) { // 询问if(!u) return {200000, -200000};if(inr(t[u], mi, ma)) return {t[u].val[0], t[u].val[1]};if(outr(t[u], mi, ma)) return{200000, -200000};pii l = query(t[u].l, mi, ma), r = query(t[u].r, mi, ma);if(inr(t[u].p, mi, ma)) return {min({l.first, r.first, t[u].p.val}), max({l.second, r.second, t[u].p.val})}; // 别忘了单点return {min(l.first, r.first), max(l.second, r.second)};
}signed main() {#ifndef ONLINE_JUDGEfreopen("i.ru", "r", stdin);freopen("o", "w", stdout);#endifint n = in(n), m = in(m), cnp = 0, rt = 0;for(int i = 1; i <= n; i ++) {for(int j = 1; j <= m; j ++) {p[++ cnp] = {{i, j}, in<int>()};}}build(rt, 1, cnp, 0);int mi[2], ma[2], lim = in(lim), ans = 0;pii t;for(int i = 1; i <= n; i ++) {for(int j = i; j <= n; j ++) {for(int l = 1, r = 1; r <= m;) { // 简单的双指针while((r - l + 1) * (j - i + 1) <= ans and r <= m + 1) r ++; // 剪枝,不可能比 ans 优就跳过if(r > m) break;mi[0] = i, ma[0] = j, mi[1] = l, ma[1] = r;t = query(rt, mi, ma);if(t.second - t.first <= lim) {ans = max(ans, (r - l + 1) * (j - i + 1));r ++;}else {l ++, r ++; }}}}out(ans);
}   
// 星間~ 干渉~ 融解~ 輪迴~ 邂逅~ 再生~ ララバイ~
http://www.jsqmd.com/news/32612/

相关文章:

  • 深度学习非专业解释
  • 内存管理-50-可读性-1-page_flags.h - Hello
  • 25.11.05
  • 在React中实现路由跳转
  • 022304105叶骋恺数据采集第二次作业
  • 2025.11.5模拟赛
  • ai编程第一次实战
  • WordPress Social Feed Gallery插件未授权信息泄露漏洞分析
  • [题解]P14094 [ICPC 2023 Seoul R] Special Numbers
  • ASP.NET Core Blazor 核心功能三:Blazor与JavaScript互操作——让Web开发更灵活
  • 测试思维的培养
  • NOIP2025模拟2 改题记录
  • 10-16
  • ASP.NET Core Blazor 核心功能二:Blazor与JavaScript互操作——让Web开发更灵活
  • 10-15
  • 10-14
  • 模拟赛 32
  • top 命令的load average和vmstat 的r列和b列的关系是什么?区别又是什么?
  • 2025-11-1
  • 2025-11-5
  • 2025-11-3
  • 2025-11-4
  • 2025-11-2
  • 网页打包EXE/APK/IPA出现乱码时怎么回事?
  • Ai元人文:个人阐述疏漏声明与系统性术语修正说明
  • 基于AWS构建的微服务集群的最佳实践
  • 六校联考 20251105C. 物品采购(judge)
  • k3s安装metallb负载均衡
  • PG故障处理:PG_AUTO_FAILOVER自动切换失败的故障处理
  • 读书笔记:分区不一定能让查询更快——关键要看使用场景