【JZOJ3633】【汕头市选2014】数数(count) (栈)
2018-02-01 08:00
260 查看
Problem
N行M列的矩形上有K个宝藏。统计包含至少1个宝藏的子矩形数量。Hint
对于20% 的数据,N,M <= 50;对于50% 的数据,N,M <= 1000;
对于80% 的数据,N <=1000;M <= 10^9;
对于100% 的数据,1 <= N,M <= 10^9; 1 <= K <= 1000; 1 <= Xi <= N,1 <= Yi <= M。
Solution
20points
不用说了吧,无脑暴力——滥用时间,枚举矩阵左上角和右下角。时间复杂度:O(n2m2)O(n2m2)。
50points
题目要求我们求至少包含1个宝藏的子矩阵数量,我们要有逆向思维,可以先求出不含任何宝藏的子矩阵数量,然后用总方案数减去它。至于不含任何宝藏的子矩阵数量,我们可以先把有宝藏的地方打个标记,然后设up[i][j]表示点(i,j)上方的第一个有宝藏的格子(包括它自己)的行。那么我们可以在O(nm)O(nm)的时间内预处理出它来。
我们先枚举一个i,表示子矩阵的下边界;然后再枚举一个j,表示子矩阵的右边界。然后我们在扫j的时候,顺便维护一个单调递减的单调栈stack,贮存我们经过的点的up。比如说,有一个3*3的矩阵如下图所示:
若红色区域为宝藏,黄色区域为我们当前做到的点,则此时stack={2,1}。如果再往后一格,stack中的所有元素就会被先后踢出栈,另加上一个2。
我们可以维护栈中每一个元素所占的宽度,那么可以很方便地更新答案。
时间复杂度:O(nm)O(nm)。
100points
50points的做法硬伤就在于难以解决图太大的局4000
面。但我们注意到此题有一个很大的图,但图中却有相对很少的、有宝藏的点。
来一波套路:离散化。
但是我们注意到,离散化以后,原本间隔很多行的两点可能会紧挨着,如下图所示:
这样一来,我们便没有计算到x,y之间的空隙对答案的贡献。于是,考虑将两点间的空行留一行,也就是说,上图应该会变成这样:
类似的,大矩阵的边界到某个点之间的空行,也留出一行。
考虑记录离散化后每一个行、每一列表示的原图的行数、列数。譬如上图中x到y的空行则记录为3,空列也记录为3;而x所占的那一行,记录为1,列也肯定记录为1(因为一个宝藏肯定只能待在一个1*1的矩阵里)。
然后仿照50points,枚举i、j,维护单调栈,但是要注意此时的行、列可能都不单单只是一行、一列。
时间复杂度:O(k2)O(k2)。
相关文章推荐
- jzoj P1421【汕头市选2012初中组】数数(count)
- 汕头市选2012初中组 数数(count) (jzoj)
- JZOJ 3.25 1421【汕头市选2012初中组】数数(count)
- jzoj3630 【汕头市选2014】分叉(树上统计)
- jzoj P1842【汕头市选2014】平均
- 【jzoj3632】【汕头市选2014】【舞伴】【状态压缩动态规划】
- jzoj P1843【汕头市选2014】小球
- [SDOI2014][JZOJ3624]数数
- 【jzoj3630】【汕头市选2014】【分叉】【树形动态规划】
- [DP]【汕头市选2012初中组】数数(count)
- jzoj P1845【汕头市选2014】约数
- 【汕头市选2014】分叉 jzoj 3630 dfs
- JZOJ3632【汕头市选2014】舞伴(perm)
- 【汕头市选2014】数数
- JZOJ3630. 【汕头市选2014】分叉(fork)
- JZOJ 3632. 【汕头市选2014】舞伴
- JZOJ 3631. 【汕头市选2014】三角(triangle)
- JZOJ__Day 3:【NOIP普及模拟】数数(count)
- JZOJ 1842——【汕头市选2014】平均
- jzoj 3631 【汕头市选2014】三角(triangle)