【BZOJ2228】[ZJOI2011]礼物(单调栈)
【BZOJ2228】[ZJOI2011]礼物(单调栈)
题面
题解
如果这个玩意不是一个三维立方体,而是一个二维的矩形,让你在里面找一个最大正方形,那么全世界都会做。
丢到三维上?似乎区别也不是很大啦。
我们先把每一层一片一片的剖开考虑,预处理以某个位置为左上角的最大正方形边长。这个很容易求,可以用单调队列做到\(O(pqr)\)。接下来枚举某个左上角,把在每一层上的这个边长全部扣下来,形成一个序列。那么要求的就是最小值乘以选择的长度的最大值。这个东西显然还是可以单调队列求。
那么这样子复杂度就变成了\(O(pqr)\),再分别按照另外两维切片,就可以考虑出所有位置的答案了。
然而我想了半天怎么求以某个点为左上角的最大正方形,就像萝卜求助,然后被萝卜狠狠狠狠狠的批判了一番:“不就搞个变量扫一遍就好了吗?”,我“???”(智商掉线.jpg,最近智商已经没了,要找点智商了。)
大概是这样的:按照某一行来做,从左往右确定每一列的答案,暴力拓展最大的合法正方形,假设边长为\(N\),那么往右移一个位置的时候直接从\(N-1\)还是枚举就好了。我实在是太菜了,这都不会。
注意一下他这个字符串的读入顺序并不是\(pqr\),而是\(qpr\)。
#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 155
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
char g[MAX][MAX][MAX];
int s[MAX][MAX][MAX];
int n[MAX][MAX][MAX];
int p[MAX][MAX];
int L[MAX],R[MAX],Q[MAX],H,T;
int a,b,c,ans;
bool check(int b,int c,int x,int y,int N)
{
if(x+N-1>b||y+N-1>c)return false;
int xx=x+N-1,yy=y+N-1;
return p[xx][yy]-p[xx][y-1]-p[x-1][yy]+p[x-1][y-1]==N*N;
}
void Calc(int a,int b,int c)
{
for(int i=1;i<=a;++i)
{
for(int j=1;j<=b;++j)
for(int k=1;k<=c;++k)
p[j][k]=s[i][j][k]+p[j-1][k]+p[j][k-1]-p[j-1][k-1];
for(int j=1;j<=b;++j)
{
int N=0;
for(int k=1;k<=c;++k)
{
while(check(b,c,j,k,N+1))++N;
n[i][j][k]=N;N-=1;
}
}
}
for(int j=1;j<=b;++j)
for(int k=1;k<=c;++k)
{
T=0;
for(int i=1;i<=a;++i)
{
while(T&&n[Q[T]][j][k]>=n[i][j][k])--T;
L[i]=Q[T]+1;Q[++T]=i;
}
T=0;
for(int i=a;i>=1;--i)
{
while(T&&n[Q[T]][j][k]>=n[i][j][k])--T;
R[i]=T?Q[T]-1:a;Q[++T]=i;
}
for(int i=1;i<=a;++i)
ans=max(ans,n[i][j][k]*(R[i]-L[i]+1));
}
}
int main()
{
b=read();a=read();c=read();
for(int i=1;i<=a;++i)
for(int j=1;j<=b;++j)
scanf("%s",g[i][j]+1);
for(int i=1;i<=a;++i)
for(int j=1;j<=b;++j)
for(int k=1;k<=c;++k)
s[i][j][k]=(g[i][j][k]=='N');
Calc(a,b,c);
for(int i=1;i<=b;++i)
for(int j=1;j<=a;++j)
for(int k=1;k<=c;++k)
s[i][j][k]=(g[j][i][k]=='N');
Calc(b,a,c);
for(int i=1;i<=c;++i)
for(int j=1;j<=b;++j)
for(int k=1;k<=a;++k)
s[i][j][k]=(g[k][j][i]=='N');
Calc(c,b,a);
printf("%d\n",4*ans);
return 0;
}
【BZOJ2228】[ZJOI2011]礼物(单调栈)的更多相关文章
- bzoj2228[ZJOI2011]礼物(gift)
据说联赛之前写题解可以涨RP 这题的输入格式半天没看懂-其实是有q层摞在一起,每一层大小都是p*r,依次输入q层的情况.那么首先我们枚举三种挖方块的姿势,分别使切出的方块的上面/前面/右面是正方形的面 ...
- 2015 UESTC 数据结构专题G题 秋实大哥去打工 单调栈
秋实大哥去打工 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/59 Descr ...
- CDOJ 1069 秋实大哥去打工 单调栈 下标处理
E - 秋实大哥去打工 Time Limit:1000MS Memory Limit:65535KB 64bit IO Format:%lld & %llu Submit St ...
- BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 8748 Solved: 3835[Submi ...
- BZOJ 4453: cys就是要拿英魂![后缀数组 ST表 单调栈类似物]
4453: cys就是要拿英魂! Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 90 Solved: 46[Submit][Status][Discu ...
- BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2326 Solved: 1054[Submit][Status ...
- poj 2559 Largest Rectangle in a Histogram - 单调栈
Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 19782 ...
- bzoj1510: [POI2006]Kra-The Disks(单调栈)
这道题可以O(n)解决,用二分还更慢一点 维护一个单调栈,模拟掉盘子的过程就行了 #include<stdio.h> #include<string.h> #include&l ...
- BZOJ1057[ZJOI2007]棋盘制作 [单调栈]
题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我们的 ...
随机推荐
- 深入理解 JS 引擎执行机制(同步执行、异步执行以及同步中的异步执行)
首先明确两点: 1.JS 执行机制是单线程. 2.JS的Event loop是JS的执行机制,深入了解Event loop,就等于深入了解JS引擎的执行. 单线程执行带来什么问题? 在JS执行中都是单 ...
- FFMPEG指令
FFmpeg是一个用于音视频处理的自由软件,被广泛用于音视频开发.FFmpeg功能强大,本文主要介绍如何使用FFmpeg命令行工具进行简单的视频处理. 安装FFmpeg可以在官网下载各平台软件包或者静 ...
- 系统重启后DNS地址默认修改修改引起的一次事故(Tomcat报错:java.net.UnknownHostException)
事故描述:公司的一个内部业务系统由于程序bug,导致系统崩溃,需要强制重启服务器.系统重启后,赶紧将业务程序启动.随后发现/etc/resolv.conf文件的DNS地址被修改成了默认地址.发现之后, ...
- sql-server安装
ubuntu安装sql-server https://docs.microsoft.com/zh-cn/sql/linux/quickstart-install-connect-ubuntu?view ...
- 《Linux内核设计与实现》 第八周读书笔记 第四章 进程调度
20135307 张嘉琪 第八周读书笔记 第四章 进程调度 调度程序负责决定将哪个进程投入运行,何时运行以及运行多长时间,进程调度程序可看做在可运行态进程之间分配有限的处理器时间资源的内核子系统.只有 ...
- R和python语言如何求平均值,中位数和众数
均值是通过取数值的总和并除以数据序列中的值的数量来计算. R语言平均值公式: mean(x, trim = 0, na.rm = FALSE, ...)#x - 是输入向量.trim - 用于从排序的 ...
- CMake系列之三:多个源文件-同一目录
同一目录,多个源文件 把前面的main.c里面的power函数单独写入到一个MathFunctions.c源文件里,目录下的文件结构如下: ./Demo2 | +--- main.c | +--- M ...
- 百度AI--自然语言处理之Java开发
参数: public class APIConstants { //设置APPID/AK/SK public static final String APP_ID = "108***&quo ...
- 菜鸟教程--AJAX
一.简介1.AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术.2.AJAX = 异步 JavaScript 和 XML.3.通过在后台与服务器进行少量数据交换,AJAX 可以使网 ...
- PHP使用MySQL实现消息队列
消息队列常用在流量削峰(秒杀场景),异步通信等地方. 大体的结构如下: 类似于消费者和生产者的关系,首先生产者在消息队列未满的时候,才将生产的产品放进消息队列中:消费者在消息队列不为空的时候,才从消息 ...