题目链接

传送门

题意

给你一个\(n\times n\)的矩形,要你求出一个面积最大的矩形使得这个矩形内的最大值减最小值小于等于\(M\)。

思路

单调队列滚动窗口。

比赛的时候我的想法是先枚举长度然后再枚举左端点,最后用单调队列来做,然后\(T\)成傻逼,赛后看大佬们的代码发现我的做法比先枚举左端点再枚举右端点多很多状态(譬如在每次长度变化的时候我的写法会从最左边开始枚举,而先枚举左端点的做法则不会再反复考虑左边的情况)。

我们先固定左端点,然后在枚举右端点的时候用两个数组记录\([L,R]\)中每一行的最大值、最小值,然后用单调队列来维护矩形中最大值减最小值小于等于\(M\)的面积,这也算是一个板子题了,比赛的时候没过还是因为思维僵化\(+\)刷题太少啊。

代码实现如下

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("D://Code//in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-8;
const int mod = 1000000007;
const int maxn = 1000000 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int t, n, M;
int bk1, bk2, tp1, tp2;
int q1[2007], q2[2007];
int mp[505][505], num1[505], num2[505]; int main() {
scanf("%d", &t);
while(t--) {
scanf("%d%d", &n, &M);
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= n; ++j) {
scanf("%d", &mp[i][j]);
}
}
int ans = 0, tmp;
for(int L = 1; L <= n; ++L) {
for(int i = 1; i <= n; ++i) num1[i] = -inf, num2[i] = inf;
for(int R = L; R <= n; ++R) {
for(int i = 1; i <= n; ++i) num1[i] = max(num1[i], mp[i][R]), num2[i] = min(num2[i], mp[i][R]);
int tmp = 0;
bk1 = bk2 = tp1 = tp2 = 1000;
for(int i = 1; i <= n; ++i) {
while(bk1 != tp1 && num1[i] >= num1[q1[tp1]]) --tp1;
while(bk2 != tp2 && num2[i] <= num2[q2[tp2]]) --tp2;
q1[++tp1] = i;
q2[++tp2] = i;
while(bk1 != tp1 && bk2 != tp2 && num1[q1[bk1+1]] - num2[q2[bk2+1]] > M) {
if(q1[bk1+1] > q2[bk2+1]) {
tmp = q2[bk2+1];
++bk2;
} else {
tmp = q1[bk1+1];
++bk1;
}
}
ans = max(ans, (R - L + 1) * (i - tmp));
}
}
}
printf("%d\n", ans);
}
return 0;
}

\(ps.STL\)里面的\(deque\)的常数巨大,以后尽量还是手写队列!

2019年牛客多校第三场 F题Planting Trees(单调队列)的更多相关文章

  1. 2019牛客多校第八场 F题 Flowers 计算几何+线段树

    2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...

  2. 牛客多校第三场 F Planting Trees

    牛客多校第三场 F Planting Trees 题意: 求矩阵内最大值减最小值大于k的最大子矩阵的面积 题解: 矩阵压缩的技巧 因为对于我们有用的信息只有这个矩阵内的最大值和最小值 所以我们可以将一 ...

  3. Removing Stones(2019年牛客多校第三场G+启发式分治)

    目录 题目链接 题意 思路 代码 题目链接 传送门 题意 初始时有\(n\)堆石子,每堆石子的石子个数为\(a_i\),然后进行游戏. 游戏规则为你可以选择任意两堆石子,然后从这两堆中移除一个石子,最 ...

  4. 2019牛客多校第三场 F.Planting Trees

    题目链接 题目链接 题解 题面上面很明显的提示了需要严格\(O(n^3)\)的算法. 先考虑一个过不了的做法,枚举右下角的\((x,y)\),然后二分矩形面积,枚举其中一边,则复杂度是\(O(n^3 ...

  5. [题解]Magic Line-计算几何(2019牛客多校第三场H题)

    题目链接:https://ac.nowcoder.com/acm/contest/883/H 题意: 给你偶数个点的坐标,找出一条直线将这n个点分成数量相等的两部分 并在这条直线上取不同的两个点,表示 ...

  6. [题解]Crazy Binary String-前缀和(2019牛客多校第三场B题)

    题目链接:https://ac.nowcoder.com/acm/contest/883/B 题意: 给你一段长度为n,且只有 ‘0’ 和 ‘1’ 组成的字符串 a[0,...,n-1].求子串中 ‘ ...

  7. 启发式分治:2019牛客多校第三场 G题 Removing Stones

    问题可以转换为求有多少个区间数字的总和除2向下取整大于等于最大值.或者解释为有多少个区间数字的总和大于等于最大值的两倍(但是若区间数字总和为奇数,需要算作减1) 启发式分治: 首先按最大值位置分治,遍 ...

  8. 2019牛客多校第三场F Planting Trees(单调队列)题解

    题意: 求最大矩阵面积,要求矩阵内数字满足\(max - min < m\) 思路: 枚举上下长度,在枚举的时候可以求出每一列的最大最小值\(cmax,cmin\),这样问题就变成了求一行数,要 ...

  9. Distance(2019年牛客多校第八场D题+CDQ+树状数组)

    题目链接 传送门 思路 这个题在\(BZOJ\)上有个二维平面的版本(\(BZOJ2716\)天使玩偶),不过是权限题因此就不附带链接了,我也只是在算法进阶指南上看到过,那个题的写法是\(CDQ\), ...

随机推荐

  1. 【Shiro学习之一】Shiro入门

    一.Shiro Apache Shiro是一个Java安全框架. 1.官网:http://shiro.apache.org/ 2.三个核心组件 Subject:即“当前操作用户”,可以指人.第三方进程 ...

  2. vim查找

    vim编辑器查找的时候,先 esc,然后 /要查找的内容,按下enter,查找下一个使用 n. 如果向向上查找使用 ?要查找的内容,按下enter,查找上一个使用n

  3. mknod命令的使用

    1.mknod命令 在Linux系统下,mknod命令可用于系统下字符设备文件和块设备文件的创建. (1)命令语法 mknod(选项)(参数) (2)常用选项说明 -Z:设置安全的上下文. -m:设置 ...

  4. jmeter 生成不重复的手机号

    String account = "${__time(yyyyMMdd,)}"+UUID.randomUUID().toString().split("-")[ ...

  5. cocos2d设置窗口标题

    //窗口标题 #ifdef WIN32 CCEGLView* pGlView=CCDirector::sharedDirector()->getOpenGLView(); if (pGlView ...

  6. webUI框架miniUI,easyUI,extJS,Bootstrap简介及简单部署

    本文为大家讲解的是webUI框架miniUI,easyUI,extJS,Bootstrap简介及简单部属,感兴趣的同学参考下 ExtJS是一种主要用于创建前端用户界面,是一个基本与后台技术无关的前端a ...

  7. 通过静态发现方式部署 Etcd 集群

    在「etcd使用入门」一文中对etcd的基本知识点和安装做了一个简要的介绍,这次我们来说说如何部署一个etcd集群. etcd构建自身高可用集群主要有三种形式: 静态发现: 预先已知etcd集群中有哪 ...

  8. MOOC Web前端笔记(三):CSS样式

    CSS样式 CSS概述 CSS--Cascading Style Shees层叠样式表 HTML定义网页的内容,CSS定义内容的样式. 内容和样式相互分离,便于修改样式. CSS语法 p{ font- ...

  9. Lombok简介、使用、工作原理、优缺点

    1.Lombok简介官方介绍 Project Lombok is a java library that automatically plugs into your editor and build ...

  10. 类例程_c#战斗程序(窗体版)

    战士类代码: class Fight { String name; int attack, speed, crit, armor;// 生命.攻击力,攻速,暴击,护甲 public int life; ...