CF1909 E,F 题解
这场的题还挺有意思的,DEF都挺有趣。
E:
题意:开关灯问题,一开始全灭,给出按按钮的限制:按了 \(x_i\) 必须按 \(y_i\) ,最后开着的灯不超过 \(\lfloor \frac n5 \rfloor\) 个,输出-1或一种方案。
这题误导人往图论方向去想,谔谔。
看到像\(\lfloor \frac n5 \rfloor\) 这样的奇奇怪怪数字,可以考虑能不能把数据分类讨论。
经典的开关灯问题:有两个重要的性质:
1.如果所有按钮全部按下,那么只有平方数的灯会亮。
2.大按钮不会影响小灯,因此每一种灯的状态一一对应于按钮的状态(扫一遍可求出)。
Solution:
发现给出的限制是按钮按的越多越好,那么全按下肯定满足限制,这时只有平方数的灯会亮,数量是根号级别的,也就是说n比较大时,按钮全按就完事了。我们发现这个临界值是n=20。
特判一个n<5时要输出-1,然后考虑n从5到19。
既然只有这几个n,可以预处理出所有满足开灯上限的按钮状态。因为开着的灯不超过三个,最多也就 \((^{19}_{\ 3})+(^{19}_{\ 2})+(^{19}_{\ 1})=1159\) 个状态,压进vector里。
每个状态遍历那m条限制,复杂度上限是 \(1159 * \sum m\) ,感觉过不去?但是由于题意的特殊性,m条限制不可能把所有状态都跑满。所有的状态都是-1的限制,只能是几乎所有的边都要选。
F:
题意:
Easy version: \(p\) 是个打乱的排列,\(a_i\) 表示 \(p\) 数列第 \(i\) 位置之前有多少小于等于 \(i\) 的数,现在给出 \(a\) 数列,求合法的 \(p\) 的方案数。
Hard version:在Easy version基础上,a数列有些位置变成了-1(任意数),求合法的 \(p\) 的方案数。
这题是对数形结合的最佳诠释。
ACM中的数形结合,比如说遇到好多区间比大小,可以把区间左端点当x轴,右端点当y轴,每个区间就转化成了一个点,通过二维偏序问题可以求出各个区间的包含关系。
Solution:
这题也是转成二维,把排列的位置转成x轴,该位置的数值转成y轴。因为是排列,所以每行只有一个点,每个位置上也只有一个数,所以每列也只有一个点。如下图,红线表示 \(p_i=i\) 。
思考a数列的含义,其实就是 \(x\leq i, y\leq i\) 的点的数量,在二维平面上是矩形内点的数量。
造成a数列上升的两个因素:1. $ i$ 位置新加入的数字小于 \(i\) ;2. 等于 \(i\) 的数字在位置 \(i\) 前面。分别对应的是下图中第 \(i\) 列加入一个点,和第 \(i\) 行加入一个点。(蓝色区域)
因为行列不冲突,所以每个蓝色区域最多填入两个点。
因为每种图案对应一个排列p,这题统计方案数的方式就从每个位置能填哪些数,改成了每个蓝框能填哪些位置。
根据a数列上升的来源我们已经知道了,每个蓝框内只能填0,1和2。
如果是零自然不用管。如果是1,那么找一个能填的地方,红线处当然可以填,其他位置只要不跟小矩形内的点冲突就行。在easy version中容易看出,第i个蓝框有 \(2*(i-1-a_{i-1})+1\) 种方案。上图中,第5个蓝框有 \(2*(5-1-3)+1\) 种方案,“3”对应的是前4个位置已经填了3个点。
如果是2,那么红线处不能填了,行填一个列填一个,容易算出是 \((i-1-a_{i-1})^2\) 种。
这里有一个重要的性质:就是我们只关心小矩形内填了几个点,而不关心具体填在哪里,所以每个蓝框的问题都是独立的,总方案数就是每个框方案数乘起来。
Hard version solution:
与easy version相比无非是蓝框范围变大了,变成几列几行内填 k 个数。一开始我以为是把k拆成1+1+2这样再推式子,发现走不通,看了题解才知道是数形结合一条路走到黑。
我们把hard version中的大蓝框拆成两个部分(粉色和紫色):
以上图为例,我们先枚举紫色部分填 \(i\) 个:紫色部分有 \(2\) 行能填,\(3\) 列能填,方案数好算:\((^3_i)*(^2_i)*i!\) 。
再看看粉色:在紫色部分填了 \(i\) 个之后,它有 \(3\) 行能填,\(5-i\) 列能填,需要填 \(k-i\) 个,方案数也好算:\((^{\ 3}_{k-i})*(^{5-i}_{k-i})*(k-i)!\)。
紫色和粉色相乘就是蓝框方案数。至于式子里的数具体是几,就用输入数据来计算蓝框的大小了。
至此,已成艺术。