项目编号:bzoj-1057

项目等级:Safe

项目描述:

  戳这里

特殊收容措施:

  首先枚举最左上角的点(记为(1,1))是黑点还是白点,这样就可以把与(1,1)不在同一对角线系的格点颜色翻转(形式化地,格点(x,y)被翻转颜色当且仅当(x+y) and 1=1),然后问题就等价于求整个棋盘中的颜色与(1,1)相同的最大子矩形/正方形,也即最大全0/1子矩阵。

  求最大全0/1子矩阵有一个著名的方法叫悬线法:(以下描述中默认为求全1子矩阵)

  •从上到下枚举每行,设当前行为i,h[j]表示第j列从第i行向上最长连续的全1串长度;l[j]表示选定子矩阵高度为h[j],最下端行号为i,且(i,j)存在于子矩阵中时其能达到的极左行号;r[j]定义类似于l[j]。

  •这样最大子矩形即为max{(r[j]-l[j]+1)*h[j]},子正方形即为max{min(r[j]-l[j]+1,h[j])2}。

  •h[j]的转移比较显然,每次i下移一行的时候,若第j列元素为1,则h[j]加一,否则h[j]赋为0。

  •对于l[j]的转移,我们可以通过行内从左向右递推求得。考虑到子矩阵必须连续,则对于cur,不断探测cur的左一位,如果发现h[cur-1]<h[j]则l[j]即cur,否则cur赋为l[cur-1]并继续探索。

  •r[j]的转移类似l[j],并且我们可以证明这种递推是均摊O(1)的。

  这样,我们就能用O(nm)的复杂度解决这个(俩)问题了。

附录:

 1 #include <bits/stdc++.h>
2 #define range(i,c,o) for(register int i=(c);i<(o);++i)
3 #define dange(i,c,o) for(register int i=(c);i>(o);--i)
4 using namespace std;
5
6 //#define __debug
7 #ifdef __debug
8 #define sub(t) t
9 #else
10 #define sub(t) __attribute__((optimize("-O2"))) inline t
11 #endif
12
13 // quick_io BEGIN HERE
14 sub(unsigned) getU()
15 {
16 char c; unsigned r=0; while(!isdigit(c=getchar()));
17 for(;isdigit(c);c=getchar()) r=(r<<3)+(r<<1)+c-'0';
18 return r;
19 }
20 // quick_io END HERE
21
22 sub(int) sqr(const int&x) {return x*x;}
23
24 static int n=getU(),m=getU(),squ=0,mat=0;
25 bool a[2005][2005];
26 int h[2005],l[2005],r[2005];
27 sub(void) work(const bool&rev)
28 {
29 memset(h,0,sizeof h);
30 range(i,0,n)
31 {
32 range(j,0,m)
33 {
34 a[i][j]^((i+j)&1)^rev?++h[j]:h[j]=0;
35 }
36 range(j, 0 , m) for(
37 l[j]=j;
38 l[j] &&h[l[j]-1]>=h[j];
39 l[j]=l[l[j]-1]
40 );
41 dange(j,m-1,-1) for(
42 r[j]=j;
43 r[j]+1<m&&h[r[j]+1]>=h[j];
44 r[j]=r[r[j]+1]
45 );
46 range(j,0,m)
47 {
48 squ=max(squ,sqr(min(r[j]-l[j]+1,h[j])));
49 mat=max(mat,(r[j]-l[j]+1)*h[j]);
50 }
51 }
52 }
53
54 int main()
55 {
56 range(i,0,n) range(j,0,m) a[i][j]=getU();
57 range(i,0,2) work(i);
58 return printf("%d\n%d\n",squ,mat),0;
59 }

SCP-bzoj-1057的更多相关文章

  1. BZOJ 1057: [ZJOI2007]棋盘制作

    Decsription 给你一个矩阵,求最大了 01相间 的矩阵. Sol DP+悬线法. 这是一个论文啊 <浅谈用极大化思想解决最大子矩形问题>--王知昆. 枚举每一根悬线,记录最左/右 ...

  2. BZOJ 1057 棋盘制作

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

  3. bzoj 1057: [ZJOI2007]棋盘制作 单调栈

    题目链接 1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 2027  Solved: 1019[Submit] ...

  4. BZOJ 1057: [ZJOI2007]棋盘制作( dp + 悬线法 )

    对于第一问, 简单的dp. f(i, j)表示以(i, j)为左上角的最大正方形, f(i, j) = min( f(i + 1, j), f(i, j + 1), f(i + 1, j + 1)) ...

  5. bzoj 1057 单调栈

    首先我们可以枚举每个一点,然后向下一直拓展到不能拓展为止,然后向下拓展的同时我们可以算出来向左最多拓展的个数,用单调栈来维护一个上升的序列,这样就类似与悬线法找最大01子矩阵了,但是对于这题01交替来 ...

  6. 【BZOJ 1057】 1057: [ZJOI2007]棋盘制作

    1057: [ZJOI2007]棋盘制作 Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的 ...

  7. BZOJ 1057: [ZJOI2007]棋盘制作 悬线法求最大子矩阵+dp

    1057: [ZJOI2007]棋盘制作 Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑 ...

  8. 悬线法 || BZOJ 1057: [ZJOI2007]棋盘制作 || Luogu P1169 [ZJOI2007]棋盘制作

    题面:P1169 [ZJOI2007]棋盘制作 题解: 基本是悬线法板子,只是建图判断时有一点点不同. 代码: #include<cstdio> #include<cstring&g ...

  9. BZOJ 1057 棋盘制作(最大01相间子矩阵)

    求最大01相间子矩阵可以转换为求最大全0子矩阵.只需把棋盘(x+y)为奇数的取反,而该问题可以用经典的悬线法O(n^2)的求解. 悬线法呢. 首先定义b[i][j],为a[i][j]向上的最大连续0的 ...

  10. BZOJ 1057:[ZJOI2007]棋盘制作(最大01子矩阵+奇偶性)

    [ZJOI2007]棋盘制作                                          时间限制: 20 Sec 内存限制: 162 MB[题目描述]国际象棋是世界上最古老的博 ...

随机推荐

  1. hdu 1451 Area in Triangle(计算几何 三角形)

    Given a triangle field and a rope of a certain length (Figure-1), you are required to use the rope t ...

  2. 【Java】字符串转json

    import org.json.JSONObject; JSONObject jo = new JSONObject(new String(需要转换的字符串));

  3. LOJ 3058 「HNOI2019」白兔之舞——单位根反演+MTT

    题目:https://loj.ac/problem/3058 先考虑 n=1 怎么做.令 a 表示输入的 w[1][1] . \( ans_t = \sum\limits_{i=0}^{L}C_{L} ...

  4. [CSP-S模拟测试]:x(数学+并查集)

    题目背景 $\frac{1}{4}$遇到了一道水题,叒完全不会做,于是去请教小$D$.小$D$都没看就切掉了这题,嘲讽了$\frac{1}{4}$一番就离开了.于是,$\frac{1}{4}$只好来问 ...

  5. Android setXfermode 模式

    参考:http://onewayonelife.iteye.com/blog/1169176  setXfermode  设置两张图片相交时的模式  我们知道 在正常的情况下,在已有的图像上绘图将会在 ...

  6. python中递归函数

    python中的 递归函数,是指的是函数在函数内部调用自己的函数 需要满足两个条件,一,需要有一个明确的终止条件 二,需要函数自己在内部调用自己

  7. mysql查看sql执行情况的几种方法

    mysql系统变量分为全局变量和会话变量,全局变量的修改影响到整个服务器,会话变量修改只影响当前的会话. 查看log日志是否开启 show variables like 'general_log' s ...

  8. BootStrap的一些基本语法

    一, 1.@using :引入命名空间 2.@model:声明强类型的数据 Model 类型 3.@section:定义要实现母版页的节信息 4.@RenderBody():当创建基于此布局页面的视图 ...

  9. Java GC算法

    转自:http://blog.csdn.net/heyutao007/article/details/38151581 1.JVM内存组成结构 JVM内存结构由堆.栈.本地方法栈.方法区等部分组成,结 ...

  10. NOIP2015D1T2 信息传递

    题目描述 有 n 个同学(编号为 1 到 n )正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为 i 的同学的信息传递对象是编号为 Ti​ 的同学. 游戏开始时,每人都只 ...