2021“MINIEYE杯”中国大学生算法设计超级联赛(4)
评测机出锅的一场,导致最后一个半小时无效时间,应该很快就能补完吧。
补完了。
[1001 Calculus]
solution
题面:给出一个函数
是否收敛。
其中
做法:注意这些集合的函数在
1 | //2021.8.1 by ljz |
[1002 Kanade Loves Maze Designing]
solution
题面:一棵树,每个点有颜色,设
做法:数据范围允许
也没想更好的做法。
1 | //2021.8.4 by ljz |
[1003 Cycle Binary]
solution
题面:一个
做法:设
为了方便说明,我们先定义以下规定:
1.
2. 若
3. 定义
接下来我们就先来证明一个重要引理:
Periodicity Lemma:若
Proof:不妨设
我们定义
其中
同理,我们写出
两者做差,得到
注意到
那么
而由于
这意味着
这便意味着
同时根据裴蜀定理,有
于是就证明
证明了引理之后,我们再回头来看这道题。
我们枚举长度
若
若
于是我们终于证明了最开始式子的正确性了。
接下来想如何求解,这其实是平凡的数论题了。
而我们考场上是用了一次莫反,注意到
当然复杂度可以优化到
下面代码当然是杜教筛了,另一种做法我就没实现过。
1 | //2021.8.4 by ljz |
[1004 Display Substring]
solution
题面:
做法:看到本质不同子串想到 endpos
,然后记录出现范围,拿这个二分就好了,这里用前缀和维护就可以
1 | //2021.8.4 by ljz |
[1005 Didn’t I Say to Make My Abilities Average in the Next Life?!]
solution
题面:给你一个序列
做法:首先,这个贡献是可以拆开来的,于是我们分别算
我们先用单调栈维护出每个点能管到的区间,记为
对于区间
这个东西看起来不太好直接维护。那我们考虑一种特殊情况,若
我们发现是可以的。当
我们现在会维护
官方题解是离线的,实际做法差不多,离线下来后就等价于
1 | //2021.8.5 by ljz |
[1006 Directed Minimum Spanning Tree]
solution
题面:给个有向图,求出以每个点为根的外向树的最小生成树。
做法:出模板题是我没想到的。
考场上因为榜的原因也没去思考这个东西。实际上队友的翻译并不完全精确,理论上翻译成最小树形图那大家就都懂了。然后 它这里的范围就告诉你要实现 Tarjan 曾经提出的 Edmond’s Algorithm 的优化做法。那就赶紧去学习一下了。
Tarjan 提出的做法和本来的基本类似,仍旧是考虑缩点,只不过利用可并堆来维护入边边权,于是就可以做到
我写的当然是左偏树了。
1 | //2021.8.6 by ljz |
[1007 Increasing Subsequence]
solution
题面:求一个排列的极大上升子序列的数量。
做法:看到这个问题,容易先写出一个 dp,即
我在考场上开始想的是单调栈,后来发现实际转移的点直接与
这样转移式至少是段连续的区间,比起之前看似容易不少。而后面那个判断式实际上是后缀最大值,这就有个标准的线段树二分做法了。
我们记录
这个做法大概比标算的分治好一点,毕竟我可以修改。
1 | //2021.8.6 by ljz |
[1008 Lawn of the Dead]
solution
题面:给一个
做法:注意到斜对角的地雷会让它俩夹的那个右上的地方变成地雷,这是所有情况的本质。而第零列和第零行可以看做全是地雷,最终情况就是这样反复变地雷。考虑一行行维护,可用线段树也可用 set
,不过线段树好写很多,不用什么讨论。
下面代码使用线段树维护线段右端点的,时间复杂度
坑:注意两端区间是可以合并的,所以不要急着插入到线段树里,需要在外面先合并线段再插入。
1 | //2021.8.6 by ljz |
[1009 License Plate Recognition]
solution
题面:给你个车牌号,输出每个字母或数字或汉字的左右端点在第几列。车牌号由点阵中的 “#” 给出。
做法:注意到除了汉字外,其它的都是一行连续的。于是先判完其他的再判汉字即可。
1 | //2021.8.6 by ljz |
[1010 Pony Running]
solution
题面:
做法:出题人利用
我们容易写出
一种是注意到系数矩阵是
另一种方法是考虑到当我知道四个点的
但似乎主元法会遇到一些困难,因为这里的
所以代码只能是
1 | //2021.8.7 by ljz |
[1011 Travel on Tree]
solution
题面:给出一棵树,有边权,每次询问
做法:好题!为什么说是好题,只是希望…理智粉
这题的
带
与虚树根的 是一个新的点( 或其他点)。 与虚树根的 是虚树根,但 不在虚树的任意一条路径上。 与虚树根的 是虚树根,但 在虚树的一条路径上。
第一种情况是容易处理的,只要在原树上处理好,那贡献就是
第二三种情况只在于判断后者条件,毕竟第三种情况是没有贡献的。而后者条件的判断似乎就是想在虚树找一条链去包含
于是我们就做好了添加一个点的所有预备工作。
那我们看一下这个复杂度,找前驱后继,还要插入一个点到虚树的
这就是我个人的 stereotype 了,我常以为添加一个信息会比删去一个信息来得容易,而这题却恰恰相反。实际上,若我们用一个 list
来维护
希望这道题能改变我一些问题的思考方向!
(代码实现比较参考 std 了属于是,因为开始没懂它是怎么去
1 | //2021.8.6 by ljz |