【题解】Solution Set - 杂题选讲「刘君实」
【题解】Solution Set - 杂题选讲「刘君实」
7/25 sh 杂题听课情况
「HNOI2012」集合选数
将不能同时取这个性质,反应在图上:互相连边。
于是这道题就等价于数独立集的个数。
一般图的独立集的个数不太好做,但是仔细思考一下,我们实际上建出来的图是网格图(因为 \(2,3\) 互质)。
而且边长规模分别是 \(\log_3n\) 和 \(\log_2 n\),考虑对其中一维状压(事实证明只能状压 \(\log_3 n\) 那一维,不然转移就成 \(n^2\) 了),然后 dp 就好了。
注意对每一个联通网格图都需要跑一遍,最后答案相乘。
时间复杂度:\(\mathcal O(\log_2n\log_3n+2^{2\log_3n}\log_2n)\)
「NOI2018」 冒泡排序
狄尔沃斯定理
该定理断言:
- 对于任意有限偏序集,其最大反链中元素的数目必等于最小链划分(覆盖)中链的数目。
- 对于任意有限偏序集,其最长链中元素的数目必等于其最小反链划分中反链的数目。
特别的对于一序列她一定是一个偏序集(只要将满足 \(i<j,a_i\le a_j\) 的 \((i,j)\) 连边,形成 Hasse 图),此时有:
- 把序列分成不上升子序列的最少个数,等于序列的最长上升子序列长度。
- 把序列分成不降子序列的最少个数,等于序列的最长下降子序列长度。
DAG 和 Hasse 图 是完全等价的,即:任意一个 Hasse 图 是 DAG,任意一个 DAG 是 Hasse 图
首先啊,注意到不合法的的情况当且仅当,存在一个长度为 \(3\) 的下降子序列。
证明的话,首先要满足不超过这个下界的话,每个元素每次都一定往她的目标方向走,也就是说她一定不会反向。考虑一个长度为 \(3\) 的下降子序列,则中间的元素一定先向左再向右,于是就不合法了。
然后根据 Dilworth 定理,即不能将整个序列划分成超过 \(2\) 个上升子序列。
因为我们最后枚举第一个不同的元素,所以 DP 定义的是向后的方案数。
因为只是不超过 \(2\) 个,这个比较好维护,于是考虑 DP。定义 \(f_{i,j}\) 表示前 \(i\) 个元素固定,最大值为 \(j\),后面 \(n-i\) 个元素任意的方案数。
**Warning: ** 时刻注意子序列是可以不用连续的!!!
枚举 \(i+1\) 的取值 \(k\),分两种情况:
- \(k>j\),则可以直接接上去:\(\sum_{k=j+1}^{n}f_{i+1,k}\)
- \(k<j\),那么 \(i+1\) 必须填当前没有填的最小值,如果之前有这样的转移,那么相当于接到那个上面去,否则相当于开一个新的上升子序列:\(f_{i+1,j}\)
则有递推关系:
然后题解就讲的比较清楚了(
最后第三个分讨的地方有问题,因为是当前第 \(i\) 项必须严格大于前面的最大值,所以答案和第一种情况一致。
道具整理
真的摆了,这个打表的结论,暂时没证。
@sh 学长的课件讲的挺清楚。(
关于暴力的 dp 递推式:
枚举当前的 \(i\),被插入的位置 \(k\):
- \(k\) 在最末尾,块的数量+1。所以 \(f_{i,j}\) 累加 \(f_{i-1,j-1}\);
- \(k\) 在最后一个元素的前面,块的数量不变。所以 \(f_{i,j}\) 累加 \(f_{i-1,j};\)
- \(k\) 在从右往左数的第一个空隙,块的数量+1。所以 \(f_{i,j}\) 累加 \(f_{i-1,j-1};\)
- \(k\) 在其她空隙,只要之前的块的数量 \(>j\),就一定能找到一个空隙,让多余的块被合并。所以 \(f_{i,j}\) 累加 \(\sum_{k=j+1}^{i-1} f_{i-1,k}\)。
(倒着枚举每次的 \(j\),就可以前缀和优化。
接着继续看课件吧(
最后答案要二倍,是因为一开始的 \(f_{2,2}=2\)。
星空列车
灯光展演
首先我们注意到一件事情:染的颜色数量并不是越多越好,最多为 \(c=\min\left(m,\left\lfloor\dfrac n2\right\rfloor\right)\)。
因为是树上的联通块,考虑将一个连通块的贡献分摊到边上。
接下来考虑先随便选一个根 \(u\),对于她的每一条连边 \((u,v)\),其有一次贡献等价于:存在一对点 \((x,y)\),\(x\) 在 \(v\) 的子树内,\(y\) 在 \(u\) 的除 \(v\) 外的子树内。
显然,最优的情况下,每个子树内的颜色互不相同且都有匹配。
如果构造题答案存在上界,考虑构造一种方案正好取到这个上界。
Motivation1: 要使这样的点对尽量的多,感性的理解一下,应该要让每一个子树大小平均,因而想到用树的重心作为根节点。
Motivation2: 子树大小小于 \(c\) 且需要颜色不同,不妨直接按 dfs 序来染色。
可以证明这个方案最优,且取到答案上界。
证明如下:
设 \(v\) 是 \(u\) 子树大小最大的一个子儿子。
-
如果 \(siz_v\ge c\):
由重心的性质,\(siz_v\le\left\lfloor\dfrac n2\right\rfloor\),那么子树外的大小之和(包括根) \(\ge \left\lfloor\dfrac n2\right\rfloor\),所以 \(v\) 子树内的所有的点(强于颜色)都能被匹配到。
同时,由于 \(v\) 子树已经包括了所有的颜色,那么对于每一个其她的子树中的颜色就一定能在 \(v\) 子树中找到匹配。
-
如果 \(siz_v <c\):
由于我们是按照 dfs 序染的色,意一个点 dfn 序为 \(i\),dfn 序为 \(i\pm c\),的点如果存在,则其颜色一定与 \(i\) 相同,且不在 \(v\) 子树内(因为 \(v\) 子树还没到 \(c\) 那么大)。
同时由重心的性质,\(siz_v\le\left\lfloor\dfrac n2\right\rfloor\),那么子树外的大小之和(包括根) \(\ge \left\lfloor\dfrac n2\right\rfloor\),点 \(i\pm c\) 至少存在其一。
对于其她子树,其大小一定 \(\le siz_v< c\),那么同理可证得。
最后注意,如果 \(n\) 是奇数的话,就考虑一下整棵树的重心(因为我们之前恰好也只有她没被考虑/匹配到),如果有多的颜色,就染新的颜色让答案加一,否则随便染(反正答案不变。
还有,实际上每棵子树内并不需要像点分治一样,再找重心递归下去。
因为我们一开始考虑的全局树根实际上上就是最坏的情况,子树内的每一条边一定能被跨过她下面节点的子树大小次。
「AGC040E」 Prefix Suffix Addition
加减
「CF1753E」N Machines
挖掘性质,剪枝题。
https://www.luogu.com.cn/article/nf9a741y
「QOJ4912」WereYouLast
最朴素的想法是直接将每次 \(n\) 的二进制表示保存在 bool
数组中。
但是显然每次修改次数最多可以到 \(\log n\) 的级别,是很劣的。
构造模型如下:
- 每次你的位置加一(初始位置为 \(0\));
- 如果你新走入的位置之前走过奇数次则停留。否则位置置为 \(0\)。
这样你第一次从 \(\log_2n\) 传送回 \(0\) 时刚好走 \(2^n−1\) 步。
手动模拟一下前面几次走法:
\(n\) | 走完后位置 | 每个位置走过次数的奇偶性 |
---|---|---|
\(1\) | \(0\) | \(\{1,0,0,0,\dots\}\) |
\(2\) | \(1\) | \(\{0,0,0,0,\dots\}\) |
\(3\) | \(0\) | \(\{0,1,0,0,\dots\}\) |
\(4\) | \(0\) | \(\{1,1,0,0,\dots\}\) |
\(5\) | \(1\) | \(\{0,1,0,0,\dots\}\) |
\(6\) | \(2\) | \(\{0,0,0,0,\dots\}\) |
\(7\) | \(0\) | \(\{0,0,0,1,\dots\}\) |
\(8\) | \(0\) | \(\{0,1,0,1,\dots\}\) |
挺神奇的,这样每次询问只需要修改 \(5\) 个 bit 维护位置,\(1\) 个 bit 维护奇偶性就好。
(我觉得我还没有完全理解到精髓😢