2.7 模拟赛总结
2.7 模拟赛总结
A. 矩阵
题意:
递归定义大小为 \(2^N\times2^N\) 的矩阵 \(Mat_N\) 为:
-
\(N=0\):矩阵中只有一个元素,这个元素是 \(1\);
-
\(N>0\):将矩阵沿横竖两条中线切割成大小均为 \(2^{N-1}\times 2^{N-1}\) 的四块小矩阵,
其中左上角的矩阵所有元素全是 \(0\),其他三个位置的矩阵都等于 \(Mat_{N-1}\)。
现在给定 \(n,x,y\),已知矩阵 \(A=Mat_n\),求 \(\sum\limits_{i=1}^{n-x}\sum\limits_{j=1}^{n-y}[A_{i,j}=A_{i+x,j+y}=1]\)。
\(n\le 2\times10^3,x,y\le2^n\).
做法:
首先考虑 \(A\) 中哪些元素等于 \(1\),这个等价于考虑 \(A\) 中哪些元素等于 \(0\)。
看到矩阵的大小永远都是 \(2\) 的整幂次,就可以自然的去想一些二进制意义下的结论。
发现,\(A\) 中左上角占全矩阵 \(\frac{1}{4}\) 面积的部分全是 \(0\),而所有属于这部分的位置 \((i,j)\) 都满足:
在二进制下,\(i\) 的最高位为 \(1\),\(j\) 的最高位为 \(0\),即 \(i\) 的最高位大于 \(j\) 的最高位。
也就是说,位置 \((i,j)\) 值为 \(0\) 的充分条件之一,是 \(i\) 的最高位大于等于 \(j\) 的最高位。
但显然这个不是唯一的充分条件,我们试图寻找其他的充分条件。
我们考虑,剩下的三部分都是 \(Mat_{n-1}\),显然这个应该与 \(Mat_n\) 具有类似的性质,
即三个 \(Mat_{n-1}\) 内部左上角的 \(0\) 区域里的所有位置 \((i,j)\),在二进制第二高位上满足大于关系。
那么,我们显然还可以继续考虑 \(Mat_{n-2},Mat_{n-3},\cdots\) 从而得到,\(A_{i,j}=1\) 的充要条件是:
\(i\) 的每一个二进制位都不大于 \(j\) 对应的那一位,即 \(i\) 在二进制下是 \(j\) 的子集。
那么,有了这个性质,我们就可以将问题做转化了,即原问题就等价于:
求所有 \((i,j)\) 的数量,满足 \(0\le i\le 2^n-x,0\le j\le 2^n-y,(i)_2\in(j)_2,(i+x)_2\in(j+y)_2\)。
而这个问题,我们可以通过 DP
来解决。
具体来说,我们考虑所有数的二进制,从高位到低位 DP
,
我们记 \(f(pos,upi,upj)\) 代表考虑 \(i,j\) 的前 \(pos\) 位,
\(i+x\) 在该位上的进位情况为 \(upi\),\(j+y\) 在该位上的进位情况位 \(upj\),
此时有多少种合法的 \((i,j)\)。
转移时只需要枚举 \((i,j)\) 在下一位的取值即可,最后答案就是 \(f(n,0,0)\)。
至于为什么看起来没有考虑 \(i,j\) 本身的大小限制,实际上是考虑了的,因为:
若不满足 \(0\le i\le 2^n-x,0\le j\le 2^n-y\) 中的一个,则最后第 \(n\) 位 \(i+x\) 或 \(j+y\) 必会有进位。
实现时需要高精度,这也是为什么位数只给到了 \(2000\)。
B. 字符串
学了SA后来补。
C. 收费系统
有 \(N\) 条地铁线和 \(M\) 个区域,每条地铁线上有若干个区域,每个区域有颜色编号。
其中,同一条线上颜色的编号先下降再上升且连续,还存在 \(S\) 个中转站连接一些相同颜色的区域,
其中中转站连接的区域可能来自不同的地铁线,且中转站颜色与其连接区域的颜色相同。
有 \(Q\) 次询问,每次给出起点和终点位置 \(st,en\),求从 \(st\) 到 \(en\) 经过的所有区域颜色种类的最小值。
\(N\le10,S\le30,M,Q\le10^5\)。
发现经过的颜色数不好处理,考虑将这个进行转化。
发现题目中有很好的性质,即:同一条线颜色编号连续,和跨线的瞬间颜色编号不变。
故我们可以证明,任意时刻我们经过的所有颜色编号形成了一段区间,用归纳证明即可。
那么,问题就变成了最小化经过颜色的最大编号减最小编号。
那么考虑一个暴力的做法,即枚举最大和最小编号,将问题转化为判定只经过某些颜色是否可行。
这个是简单的,只需要暴力建边跑传递闭包即可。
尝试优化,我们显然可以少枚举一维,比如只枚举最小值,然后最小化经过的最大值。
这样复杂度变得更优了,但无论是枚举一维还是多次跑最短路,其中任意一个的复杂度就已经爆了。
我们首先解决枚举最小值的问题,即我们考虑这个最小值在何处取到。
我们发现,最小值只会在所有中转站的颜色编号,以及每条线编号的转折点处取到,
而这些位置的数量是 \(O(N+S)\) 的,是一个很小的值。
我们将这些点记作关键点,则枚举最小值就可以简化为枚举按颜色编号排序后的关键点。
那么,我们唯一还需要优化的问题,是每次询问都跑一遍最短路,
而这个在引入了关键点的想法后也变得简单了,具体方法如下。
首先,如果起点和终点都在同一条地铁线上,则我们就绝不会跨线,这种情况可以判掉。
那么,剩下的情况所对应最优解的方案,就一定具有如下的形式:
我们先从起点出发,在起点所在的线上走一段距离,到达了其左边或右边的第一个关键点;
此时我们会进行抉择,即我们可能直接跨线,也可能继续走这条线;
然后,可能经过一系列的行走和跨线,我们到达了终点所在的线上,终点左右两边的第一个关键点;
最后,我们再进行一段行走,到达了终点。
我们发现,无论如何我们都不可能绕开一些特殊的位置,即起点和终点左右两边的第一个关键点。
那么,我们考虑分别枚举,我们在从起点出发和到达终点时,选择了左边还是右边的第一个关键点,
则问题就转化为了起点和终点都是关键点的形式,而这个是好做的,
我们只需要对每种最小值,都预处理出:任意一对关键点间路径上,颜色编号最大值的最小值即可。
这里的预处理可以用 \(O((N+S)^4)\) 的暴力floyd
,则总复杂度即为 \(O((N+S)Q+(N+S)^4)\)。