【BZOJ2228】[ZJOI2011]礼物(单调栈)

题面

BZOJ

洛谷

题解

如果这个玩意不是一个三维立方体,而是一个二维的矩形,让你在里面找一个最大正方形,那么全世界都会做。

丢到三维上?似乎区别也不是很大啦。

我们先把每一层一片一片的剖开考虑,预处理以某个位置为左上角的最大正方形边长。这个很容易求,可以用单调队列做到\(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]礼物(单调栈)的更多相关文章

  1. bzoj2228[ZJOI2011]礼物(gift)

    据说联赛之前写题解可以涨RP 这题的输入格式半天没看懂-其实是有q层摞在一起,每一层大小都是p*r,依次输入q层的情况.那么首先我们枚举三种挖方块的姿势,分别使切出的方块的上面/前面/右面是正方形的面 ...

  2. 2015 UESTC 数据结构专题G题 秋实大哥去打工 单调栈

    秋实大哥去打工 Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/59 Descr ...

  3. CDOJ 1069 秋实大哥去打工 单调栈 下标处理

    E - 秋实大哥去打工 Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%lld & %llu Submit St ...

  4. BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 8748  Solved: 3835[Submi ...

  5. BZOJ 4453: cys就是要拿英魂![后缀数组 ST表 单调栈类似物]

    4453: cys就是要拿英魂! Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 90  Solved: 46[Submit][Status][Discu ...

  6. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2326  Solved: 1054[Submit][Status ...

  7. poj 2559 Largest Rectangle in a Histogram - 单调栈

    Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19782 ...

  8. bzoj1510: [POI2006]Kra-The Disks(单调栈)

    这道题可以O(n)解决,用二分还更慢一点 维护一个单调栈,模拟掉盘子的过程就行了 #include<stdio.h> #include<string.h> #include&l ...

  9. BZOJ1057[ZJOI2007]棋盘制作 [单调栈]

    题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我们的 ...

随机推荐

  1. Luogu P1330 封锁阳光大学

    这是一道神坑题! 刚开始看了题还以为是Tarjan(我也不知道Tarjan有什么用). 然后发现这是染色问题的模板题! 找到没有染色的点,然后将它涂成1(一共只有1,2两种颜色) 与它相连的点进行广搜 ...

  2. shell脚本中的数据传递方式

    shell中支持的数据传递方式 主要有那么几种: 变量.管道.结果引用.重定向+文件.以及xargs. 变量方式: 1. 定义变量: 变量名=值 2. 使用变量: $变量名 管道方式: 统计当前文件夹 ...

  3. 51nod 1295 XOR key 可持久化01字典树

    题意 给出一个长度为\(n\)的正整数数组\(a\),再给出\(q\)个询问,每次询问给出3个数,\(L,R,X(L<=R)\).求\(a[L]\)至\(a[R]\)这\(R-L+1\)个数中, ...

  4. 2.RapidIO串行物理层的包与控制符号

    转自https://www.cnblogs.com/liujinggang/p/9932150.html 一.RapidIO串行物理层背景介绍 上篇博文提到RapidIO的物理层支持串行物理层与并行物 ...

  5. 关于用tesseract和tesserocr识别图片的一个问题

    对于像我这样初学python网络爬虫的freshman来说,软件的准备和环境的配置能让我们崩溃.其中用刚安装好的tesseract和tesserocr库测试识别验证码就是其中一例. 这里我要测试的验证 ...

  6. 代码规范(RL-TOC)用更合理的方式写 JavaScript

    代码可以改变世界 不规范代码可以毁掉世界 只有先学会写规范的代码,才可以走的更远 编程语言之间有很多编程规范都是通用: 命名 不要用语言不明的缩写,不用担心名字过长,名字一定要让别人知道确切的意思; ...

  7. JS 实现计算一段文字中的字节数,字母数,数字数,行数,汉字数。

    看到了匹配,第一个想到了用正则表达式,哈哈,果然很方便.不过正则表达式高深莫测!我还没有研究明白啊..目前学了点皮毛.代码如下: <!DOCTYPE html PUBLIC "-//W ...

  8. Linux内核分析 第七周 可执行程序的装载

    张嘉琪 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 Linux内核分析 第七 ...

  9. Leetcode——258.各位相加【水题】

    给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数. 示例: 输入: 38 输出: 2 解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2. 由于 2 是一位数,所 ...

  10. ajax 异步请求 代码

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...