2022.2
2022.2
只记录一些我喜欢的题 还有一些模拟赛时没想到的 key observation
剩下的题只是因为我不会
2.8
T1
有时候不合法的决策一定不优于答案,这时候可以扩大决策集合。
这题就令 的 都转移到 就裸的斜率优化了。
T2
话说这个按编号二进制下每位是否为 分类是不是很常见的思路啊。
2.10
T1
给你 个数,其中有 个奇数,你可以花费 的代价把 和 同时减 ,问最小花费。
但怎么建图?
考虑只有偶数,对 的一次操作看成 之间的一条边,所有操作构成一个图,每个点的度数都是偶数,所以一定可以拆分成若干个环,我们给环上的边定向(顺时针还是逆时针无所谓),每个点的入度都等于出度,这样我们建费用流时就可以把每个点拆成入点和出点,源点向出点连流量 的边,入点向汇点连 的边,出点和入点之间连流量正无穷,费用 的边。
加上奇数的话,所有操作构成的图就不能全部拆成环,还会多出一些首位是奇数点的链,注意到 非常小,于是可以 枚举那些奇数点是入度比出度大 (其余的就是出度比入度大 ),从源点连的或连向汇点的边流量就是 或 ,这样就做完了。
T3
真的是太喜欢这个题了
第一次看到点分树这种用法
题意大概是给你一棵树,点 向树上距离 不超过 的点连边,形成一个有向图,求缩点 DAG 中入度为零的点个数。
暴力建图做 tarjan 就 了,寄,原因在于边数太多
如果有一种复杂度可以接受的 dfs 方式搜一遍所有点,那 dfs 序的逆序就是拓扑序(忽略一个强连通分量里的顺序),在按拓扑序搜一遍就得到零入度点的个数了。
点分树
我们记录下每个点的各级分治重心,和每个点作重心时他那层的所有点,并按到重心距离排序。
这部分空间复杂度是 ,我们再对每层维护一个指针(类似当前弧优化),这样遍历每层的复杂度也保证了。
我们现在 dfs 到点 ,然后我们以此考虑 的各级分治重心,从指针指的位置继续往下 dfs,指针指的点到 的距离超过 就 break 掉,继续考虑下一个分治重心。
然后我们就发现整个 dfs 的复杂度就是 ,What a coincidance!
2.12
T1
区间DP,感觉不太难啊,为什么做不出来
T2
挺好一个题,可惜被一车人的 暴力吊起来艹,我 却毫无悬念拿了 pts /fn
一个 key observation 就是答案的边一定在最小生成树上。
然后就只需对每个点维护其在 MST 上的孩子,具体地,我们要维护:
- 该点的孩子的颜色集合
- 每种颜色对应的边权的集合
- 这些颜色对应的边权的最小值的集合
- 所有点的各颜色对应的边权的最小值的集合的最小值的集合(其实就是全局的答案)
修改依次修改每个集合即可,总复杂度 。
总结:是一道非常好的 STL set 练习题
T3
给你序列 ,计数满足下列条件的长 的正整数序列
- 序列中不存在
模数 ,
题面简洁,感觉像经典题(?
先设计 DP, 考虑用总数减去有 的串个数,后者枚举最小 计算。
记 的前缀积为 , 为 的逆元,则有
这个转移像个卷积,于是想到分治 NTT,因为转移一定有 ,所以我们分治的时候,用左面的 和右面的 卷,再转移到对应位置(可能再区间外)。
再减小常数,我们只需要计算出 的 ,最后 计算 即可,还有, 的区间是不用做 NTT 的,因为会转移到范围外。
跑 ,彳亍。
2.14
T1
题意好长...... 不写了。
好喜欢这个题,所以让我复述一下题解
先考虑没有问号的情况,我们维护一个栈,两个两个操作,每次我们可以 :
- 将两位依次压入栈中
- 将第一位与栈中全部元素合并后,再将第二位压入栈中
栈中的情况可以用一个关于下一个压入元素的函数描述,即 表示当 时返回 , 时返回 。根据上面两种情况,我们很容易得到当前栈加入两个数后的新栈的情况,这样 表示到第 位,栈的状态为 是否可行,状态数为 。
加上问号,我们可以考虑 DP 套 DP,把 种 是 还是 状压起来,复杂度是 。
T2
看了两个小时硬是没看出来 SG 函数是啥,我自裁
每个棋子是独立的,总的 SG 函数就是每个棋子的 SG 函数异或和,这很难想到吗?
单个棋子的 SG 函数就是它到子树内距它最远的点的距离(这个倒很容易猜到)。
然后就变成数据结构题了,树剖维护,还有就是看到这种最远距离应该能想到直径,所以把直径拎出来做要容易些,不过依然有不少细节要分类讨论,码了 5.3K,十分舒适。
T3
一眼看好裸的最大权闭合子图
复习了一下建图方式
- 对所有正权点 ,连边 ,容量为点权
- 对所有负权点 ,连边 ,容量为点权绝对值
- 原图中所有边也都连出来,容量为正无穷
则有,最大权闭合子图的权值 正点权之和
这个题有一个问题就是选出的子图不能为 ,所以我们要依次删掉每个点强制选它,但每次建图跑网络流复杂度不能接受,不过因为每次我们都只改了一条边的容量,所以不用重新建图,只需再残量网络上退流,再重新增广即可。
[NOI2012] 美食节 这个题好像也是,有空看看。
2.16
T1
一个小结论,线性基 能表示 当且仅当把 消成对角基之后的第 行只有第 列为 。
然后这个题我只会 , 的做法没听懂/dk/dk/dk
T2
参考 IOI2022国家集训队论文 彭博《图染色问题初探》
众所周知的四色定理指出,任意一个平面图都可以四染色,然而构造方案却不太容易,不过对平面图的五染色却存在很简单的构造方法。
先证引理
:任意一个平面图中一定存在度数小于等于 的点
记平面图的点数为 ,边数为 ,联通块数为 ,把平面划分成的区域个数为 ,由平面图的欧拉定理有 。因为每个平面区域至少由三条边围成,每条边被两个平面区域共享,所以有 ,两个不等式相加得到 。所有点的度数之和 ,由抽屉原理,必然存在一个点的度数小于等于 。
接下来给出五染色构造方案
对于平面图 ,找出一个度数小于等于 的点 ,删去 及与其相连的边,得到平面图 ,我们归纳假设已经构造了 的五染色方案,现在要给 染色。
如果与 相连的点小于 个或者有相同的颜色,那么 可以直接染色,否则,我们记与 相连的点为 , 到 顺时针排列,不妨设 的颜色为 ,我们从 出发找到所有与其相邻颜色为 的点,再从这些点出发找到与它们相邻的所有颜色为 的点,依此类推,得到一颗颜色交错的树 ,如果 ,那我们可以把 中所有点由颜色 变成 , 变成 ,然后把 染色 。如果 ,我们再从 出发对颜色 和 做相同操作,记得到的交错树为 ,由平面图性质,一定有 (因为 到 的路径和 到 的路径一定相交),将颜色 和 交换后,我们就可以把 染色为 。
这样我们就有了平面图五染色的 构造算法。
回到这道题,因为所给图的特殊性质,一定存在度数小于等于 的点,我们可以用类似方法构造四染色。
T3
赛时已经想到正解了可惜抱零了,赛后重构一遍代码,码了 5.6K 终于过了/tuu
因为是自己想的,所以不写题解了
2.18
T1 是垃圾题,T2T3 都没听懂,完了。
2.19
T1
我写的题解做法,不过好像写的比别人都长(?)
题意:
给你一个长度为 的序列,初始每个点的颜色都不同,每次操作合并两个颜色,求最短的区间 的长度,使 中包含所有颜色。
这个题也是,真是太喜欢了
首先肯定想到启发式合并,这样就转化为 个单点修改。
然后,看到颜色种类,就想到了记 表示 前边第一个颜色和 相同的位置。
但这个并不是固定区间的询问,怎么处理,我们非常巧妙地记 ,这个 就是 做左端点时使区间合法的最近的右端点。现在我们看看如何维护 。
我们每次会修改一个点的 (一定是使 值变大了),这会使一些点的 值变小。假设我们修改了 ,容易发现受到影响的 一定是满足 的,而且这些 一定是连续的一段(因为 是单调不下降的),修改之后这一段 会被分裂成若干段。我们用线段树维护 ,我们在线段树上二分找出满足 的区间,然后暴力地一段一段修改即可(区间赋值)。这样的复杂度是正确的,考虑最多会产生 个段,而每次操作最多会造成一次两个段的合并,所以这样的区间修改总共只有 次。
还有一个问题,如何求出新的 ,也就是说如何求最大的 使 ,考虑再开一个线段树维护 及其后缀最小值,这样就可以线段树上二分求出 。
最后还有一个小问题,并非所有的 都能作为答案,设 是最靠后的满足 包含所有颜色的位置,那么答案应该是 的 的最小值, 随着不断修改操作是单调的,直接一个指针维护就好了。
这样就以 的复杂度做完了!
T2
有 个选手编号 到 ,初始时,有一个数字 ,选手 到 依次选择是否进行操作,选手 进行操作可以将 变为 。最终的 就是胜者的编号。一个选手进行操作当且仅当他能获胜,且不进行操作无法获胜。
序列 最初给定,之后 次单点修改,每次你要求出胜者编号。
记 ,因为进行操作的人只会令 变成他自己,所以 是无用的,从 向 连边,形成一个内向树森林。
设 表示若当前 , 能不能赢,则有 当且仅当 ,这样树形 DP,最后 号节点编号最小的等于 的儿子就是胜者,若没有,答案就是 。
带上修改操作,我们就在 LCT 上动态 DP 就可以了,重儿子的转移可以写成 的形式( 适当地取 )。
23 号也有一个 LCT 做的动态 DP,其实写起来感觉差不多。
T3
给你 AC 自动机的 trie 树和 fail 树(根不确定),请你构造出一个符合条件的 AC 自动机。
题解垃圾 做法也没看懂,实际上做到 还是比较简单的说。
先假定确定了根怎么做(之后再说怎们找根)
考虑 fail 树,根节点每个子树显然是一个相同的字符,所以直接给每个点标好字符,(一些显然不合法的情况要判掉,比如 fail 边从 trie 上深度浅的点指向深的点)。
然后要检查 的 fail 边指向的点是否是从 开始跳 fail 边第一个遇到的有和 相同字符孩子的点。我们在 fail 树上 dfs,在过程中维护 表示上一个遇到的有 孩子的点,这个很好在 dfs 以及回溯过程中维护。还有一些情况比如 trie 树上有一个节点两个孩子被赋上了相同字符也要判掉。
现在我们考虑怎么找根,如果两点 之间既有 trie 边又有 fail 边,那就说明当前点对应的字符串有长度为 的 border,那它的循环节就是 ,也就是说,所有这样的公共边构成从边出发的一条条链(一个爪子形),度数大于 的点就是根。
如果所有公共边构成的是一条链,我们考虑链上一个点 在 trie 树上的邻居,它代表形如 这样的串,从它出发跳 fail 边,回到链上,假设跳到了链上的点 ,那么 代表的要么是 ,要么是空串,所以根节点一定是 或 在链上的邻居,逐个检查这三个点即可。
这样就做完了!
2.21
今天题相对来说简单多了啊
T1
题意很容易转化成求 LIS 以及哪些位置在所有可能的 LIS 中。从两边分别 DP 并统计方案数,对每个位置检查其两侧的方案数乘积是否等于总方案数(可能会很大,记得取模)
想到 DAG 必经边的经典做法,这个题就很容易想到了。
T2
题意
一棵 个节点的树,每个点可以填一个 中的整数,需满足相邻两个节点上的数互质。对每个点求其在所有合法方案中上面的数之和。
,对 取模。
直接 DP, 表示点 填 在其子树内的方案数,转移就是
(这里忽略了 的限制, 为值域,具体实现时把不在 范围内的 设为 即可)
直接莫反
后面这一大坨都可以 处理出来,这样整个 DP 以此就是 的。
对每个点求答案,换根 DP 就可以。
还有,关于换根的写法,我们可以记录每个点孩子前缀和后缀的 DP 值,这样换根的时候就避免了减去贡献,有的时候会简单很多。
T3
转化后的题意大概是给一个括号串,区间询问,求区间内最长的合法括号序列。
把左括号看作 ,右括号看作 ,前缀和之后就是一个若干山峰状的序列,就是求区间内注水,形成的最长连续水面长度(非常形象)
首先能想到 的回滚莫队。
然后还有一个做法是倍增,记 表示 右面第一个比它大的位置, 同理,答案一定是一个区间 或 。我们倍增地跳 和 ,就可以在线 单次询问了。
稍微想想好像也能做到 单次询问。总之都可以通过。
2.23
T1
容易得到 DP
DP 选的根节点必须度数大于等于 ,否则答案就是 。
加上 Link,cut 操作,考虑在 LCT 上维护动态 DP,一个节点 从重儿子的转移可以写成分段函数
存在轻儿子 DP 值为 ,
不存在
其中 是所有轻儿子的 DP 结果。
这个分段函数是容易复合的,所以就可以做了(动态 DP 能维护的奇怪东西增加了!)
几个实现细节:
- 考虑有换根操作(链翻转),所以维护一个从上到下的复合和一个从下到上的复合,reverse 的时候直接 swap 两者即可
- 为了得到一个实链顶端的 DP 值,我们发现给整个链上的函数代入 是不对的,所以我给维护的函数加了一段,代入 得到的是链顶的 DP 值
- 把 link 到 上的时候要先 access 一下 ,否则上面虚边的信息都错了(调了好久)
T2
原题:https://blog.csdn.net/weixin_45313881/article/details/104032690
所以就不写题解了,这道题还是很好的。
能不能用这道题解法求边三联通分量?
2.27 Update:好的,A 掉了洛谷模板题,看来是能的 https://www.cnblogs.com/sapphire162/p/15941274.html
T3
寄吧题,毫无难度只需大力分类讨论去构造。(但我也没切,好像没资格这么说)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!