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

题面

BZOJ

洛谷

题解

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

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

我们先把每一层一片一片的剖开考虑,预处理以某个位置为左上角的最大正方形边长。这个很容易求,可以用单调队列做到\(O(pqr)\)。接下来枚举某个左上角,把在每一层上的这个边长全部扣下来,形成一个序列。那么要求的就是最小值乘以选择的长度的最大值。这个东西显然还是可以单调队列求。

那么这样子复杂度就变成了\(O(pqr)\),再分别按照另外两维切片,就可以考虑出所有位置的答案了。

然而我想了半天怎么求以某个点为左上角的最大正方形,就像萝卜求助,然后被萝卜狠狠狠狠狠的批判了一番:“不就搞个变量扫一遍就好了吗?”,我“???”(智商掉线.jpg,最近智商已经没了,要找点智商了。)

大概是这样的:按照某一行来做,从左往右确定每一列的答案,暴力拓展最大的合法正方形,假设边长为\(N\),那么往右移一个位置的时候直接从\(N-1\)还是枚举就好了。我实在是太菜了,这都不会。

注意一下他这个字符串的读入顺序并不是\(pqr\),而是\(qpr\)。

  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4. #define MAX 155
  5. inline int read()
  6. {
  7. int x=0;bool t=false;char ch=getchar();
  8. while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
  9. if(ch=='-')t=true,ch=getchar();
  10. while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
  11. return t?-x:x;
  12. }
  13. char g[MAX][MAX][MAX];
  14. int s[MAX][MAX][MAX];
  15. int n[MAX][MAX][MAX];
  16. int p[MAX][MAX];
  17. int L[MAX],R[MAX],Q[MAX],H,T;
  18. int a,b,c,ans;
  19. bool check(int b,int c,int x,int y,int N)
  20. {
  21. if(x+N-1>b||y+N-1>c)return false;
  22. int xx=x+N-1,yy=y+N-1;
  23. return p[xx][yy]-p[xx][y-1]-p[x-1][yy]+p[x-1][y-1]==N*N;
  24. }
  25. void Calc(int a,int b,int c)
  26. {
  27. for(int i=1;i<=a;++i)
  28. {
  29. for(int j=1;j<=b;++j)
  30. for(int k=1;k<=c;++k)
  31. p[j][k]=s[i][j][k]+p[j-1][k]+p[j][k-1]-p[j-1][k-1];
  32. for(int j=1;j<=b;++j)
  33. {
  34. int N=0;
  35. for(int k=1;k<=c;++k)
  36. {
  37. while(check(b,c,j,k,N+1))++N;
  38. n[i][j][k]=N;N-=1;
  39. }
  40. }
  41. }
  42. for(int j=1;j<=b;++j)
  43. for(int k=1;k<=c;++k)
  44. {
  45. T=0;
  46. for(int i=1;i<=a;++i)
  47. {
  48. while(T&&n[Q[T]][j][k]>=n[i][j][k])--T;
  49. L[i]=Q[T]+1;Q[++T]=i;
  50. }
  51. T=0;
  52. for(int i=a;i>=1;--i)
  53. {
  54. while(T&&n[Q[T]][j][k]>=n[i][j][k])--T;
  55. R[i]=T?Q[T]-1:a;Q[++T]=i;
  56. }
  57. for(int i=1;i<=a;++i)
  58. ans=max(ans,n[i][j][k]*(R[i]-L[i]+1));
  59. }
  60. }
  61. int main()
  62. {
  63. b=read();a=read();c=read();
  64. for(int i=1;i<=a;++i)
  65. for(int j=1;j<=b;++j)
  66. scanf("%s",g[i][j]+1);
  67. for(int i=1;i<=a;++i)
  68. for(int j=1;j<=b;++j)
  69. for(int k=1;k<=c;++k)
  70. s[i][j][k]=(g[i][j][k]=='N');
  71. Calc(a,b,c);
  72. for(int i=1;i<=b;++i)
  73. for(int j=1;j<=a;++j)
  74. for(int k=1;k<=c;++k)
  75. s[i][j][k]=(g[j][i][k]=='N');
  76. Calc(b,a,c);
  77. for(int i=1;i<=c;++i)
  78. for(int j=1;j<=b;++j)
  79. for(int k=1;k<=a;++k)
  80. s[i][j][k]=(g[k][j][i]=='N');
  81. Calc(c,b,a);
  82. printf("%d\n",4*ans);
  83. return 0;
  84. }

【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. Python爬虫利器二之Beautiful Soup的用法

    上一节我们介绍了正则表达式,它的内容其实还是蛮多的,如果一个正则匹配稍有差池,那可能程序就处在永久的循环之中,而且有的小伙伴们也对写正则表达式的写法用得不熟练,没关系,我们还有一个更强大的工具,叫Be ...

  2. Zabbix实战-简易教程--DB类--ClickHouse

    一.ClickHouse介绍 Clickhouse是一个用于联机分析处理(OLAP)的列式数据库管理系统(columnar DBMS). 传统数据库在数据大小比较小,索引大小适合内存,数据缓存命中率足 ...

  3. 开启C语言的学习之门

    本人是一枚工业界的码农,为了职业道路越来越宽广决定向上位机方面进军,C语言曾经在大学里面学过点皮毛但是离应用远远不够,尽量每天在工作之余更新自己学习的进度,同时也希望有大神能给予在编程道路上的指导,话 ...

  4. LVS负载均衡下session共享的实现方式-持久化连接

    之前简单介绍LVS负载均衡的高可用方案实施,下面详细说明LVS的session解决方案: LVS算法中,SH算法可以实现将同一客户端的请求总是发送给第一次指定的RS,除非该RS出现故障不能再提供服务. ...

  5. Git常用命令梳理

    在日常的Git版本库管理工作中用到了很多操作命令,以下做一梳理: 查看分支列表,带有*的分支表示是当前所在分支 [root@115~~]#git branch 查看分支详细情况 (推荐这种方式) [r ...

  6. Python运算符-4

    #and or not #优先级,()> not > and > or print(2 > 1 and 1 < 4) print(2 > 1 and 1 < ...

  7. [转]java实现,输入数据,空格继续,回车结束输入

    普通版:可输入,可输出.带详细的注释 import java.util.Scanner; public class SumDemo { public static void main(String[] ...

  8. ### The error may involve defaultParameterMap ### The error occurred while setting parameters

    Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Query was empty; bad SQL grammar [ ...

  9. PAT 1012 数字分类

    https://pintia.cn/problem-sets/994805260223102976/problems/994805311146147840 给定一系列正整数,请按要求对数字进行分类,并 ...

  10. Linux运维工程师必须掌握的基础技能有哪些?

    这个问题挺好的,回答这个问题也是对自身的审查,看看自己还欠缺哪些.(所以我估计得好好思考下,也许下一刻我就会突然惊醒,发现我还是战⑤渣) 首先限定在Linux运维工程师上 回答仅代表我想到,不代表我都 ...