2023暑假做题小记
怕是最后一个暑假好好学 OI 了,好好卷,争取弥补高一的遗憾吧。
7.17 update:意识到一件事,全记在这好像有点乱,记多了也容易卡,考虑把一些专题单开一块……
7.22 update:牛客多校
7.7
【UER #1】DZY Loves Graph
乍一眼一看,加边、删边、回溯三种操作,后来发现漏看了一些重要的东西:
- 每次加的边长度单调递增,这意味着如果只有加边操作第一次形成最小生成树后答案一直会是这棵树。
- 删最大的 \(k\) 条边,这意味着一旦破坏了最小生成树不可能有别的边代替删除的边使其再次连通。
- 回溯只回溯前一个操作,且不会连着回溯。
- 每条边只会被真实地删一次(不包括回溯掉的)
用按秩合并优化的并查集维护图,单次加边 \(O(\log n)\) ,单次删边 \(O(1)\) 。
回溯的话,如果前一个为 \(\text{Add}\) ,那就直接加边删边。如果前一个为 \(\text{Delete}\) ,那删边操作看删完后是否破坏之前的生成树(或本来就没有),不用去真的删边。
复杂度 \(O(m \log n)\)
牛客练习赛113
D
转化题意后就是求模 \(n\) 意义下的一个二元同余方程,考虑枚举其中一元,在 \(O(n)\) 的时间内可取遍模 \(n\) 意义下所有余数,以此算出另一元,暴力枚举统计即可。
F&G
一个数组中最多可能有两个元素出现的次数不少于一半,且只有在两种元素各占一半的时候取到两个最多。考虑枚举最多的元素是哪一个,设元素 \(x\) 一共有 \(s\) 个。那它的贡献即为:
最后要把存在两个元素各占一半的情况减掉。
\(\text{F}\) 直接按上式枚举统计即可,\(\text{G}\) 把带 \(i\) 的部分分离出来,剩下的可递推计算。
7.8
The Untended Antiquity
考虑用 \(\text{Hash}\) 的思想,每次操作把墙围起来的区域加上一个随机值,撤销时就减掉,不难发现两方块连通当且仅当它们的值相等。
用二维树状数组维护,采取 \(\text{unsigned long long}\) 自然溢出。
7.9
P6982 [NEERC2015] Jump
随机化大法好!核心思路一共两步,第一步先试出一个串满足有 \(\frac{n}{2}\) 个位置符合,然后通过反转相邻两位的反馈值确定哪些位置属于一类(匹配的/未匹配的)。
瓶颈在于第一步,确定性算法最少需要 \(n\) 步(从全 \(0\) 到 全 \(1\) 必然有一个串是 \(\frac{n}{2}\)),但如果每次随机给出一个串,那 \(499\) 次不能得到 \(\frac{n}{2}\) 的概率是 \(\left ( 1- \frac{\binom{n}{\frac{n}{2} } }{2^n} \right ) ^{499}\),约为 \(0.00003\)。除非够非
CF1787G
7.10
CF920E Connected Components?
大胆猜想图的性质,连通块的数量在 \(n\) 很大的时候不会很多,用 \(\text{bfs}\) 加 \(\text{queue}\) 优化暴力找连通块(复杂度证明不太会/kk)。题解区是抽屉原理,觉得很妙。
CF1508C Complete the MST
发现异或和的限制是吓人的,可以将为给定边权的边中一条边赋为该异或值,其它边设为 \(0\),可以证明这时他们的和最小,只需考虑哪条边不为 \(0\)。容易发现当未定边形成环时,有值的那条未给定边一定不会计入最小生成树,而未给定边数大于等于 \(n\) 时,它们必然能形成环,即 \(\frac{n \times (n-1)}{2} - m \ge n\) 时,解得 \(n \ge 634\) ,用CF920E的方法把只由未给定边构成的连通块找出来,再并查集求最小生成树 。剩下的部分暴力并查集 \(O(n^3)\) 可过。
CF1749E Cactus Wall
题意是在矩形网格中通过种仙人掌使上下两边不连通,仙人掌的四连通里不能有仙人掌,问是否可行与最少种植的构造方案。
感性理解是通过走一些 "#" 组成的斜着的路径使左边与右边连通,然后想到用 \(\text{dp}\) 从左往右转移,但发现这个路径还可以拐回来,有后效性了。
放在图论专题里,肯定是图论做法。先把输入给的图就不符合要求的判掉,然后建立一个源点向左边第一列的格子连边,再将右边最后一列的格子向建立的一个汇点连边。网格中间的话走到 "." 的格子上边权为 \(1\) ,走到 "#" 上边权为 \(0\) ,最后判一下走不到的 "."。用 \(\text{dijkstra}\) 求最短路,记录路径求方案,是否连通判有无解。
CF1693C Keshi in Search of AmShZ
需要对 \(\text{dijkstra}\) 有深刻的理解……
一开始直观的想法是把一条从 \(1\) 到 \(n\) 的路径上的所有点其他的出边都堵上,以确保那个人一直沿着这条路径走。以为很对啊,但问题是这道题有重边,假设两个点之间用一条边直接相连,但这条边叠了 \(800\) 条,还有一条经过另一个点的两条边组成的路径,其中每条边也叠了 \(800\) 条。如果按照之前的想法,那一次最少要堵 \(800\) 条边,但事实上什么都不做,让这个人随便走最多只要 \(2\) 步就能走到。
之后又想到求 DAG 最长路,把带环的图堵成 DAG,平衡堵路耗费的次数和 DAG 最长路的长度,但发现都不好做
其实离正解已经很接近了。设 \(d_x\) 表示第 \(x\) 个点到 \(n\) 的最少步数,显然为了保证在任何情况下都在一定步数内到达,只需考虑最坏情况,即优先往 \(d_x\) 大的地方走。而为了缩短到达 \(n\) 的时间,应该堵掉一些指向 \(d_x\) 相对较大的点的边。所以现在要考虑的是如何平衡这二者。
仔细回想 \(\text{dijkstra}\) 的本质,是一种贪心,每次找出的往外扩展的点的 \(d_x\) 是单调不降的。建立原图的反图,在反图上跑 \(\text{dijkstra}\),每个点可以被松弛的次数就是该点在原图中的出度,优先被松弛的边来源的那个点(原图中该出边指向的一个点)的 \(d_x\) 一定是当前没被松弛的边对应的点中最小的,因此可以很方便的知道这时需要堵多少条边(出度减当前松弛次数)才能走这条边。记当前点为 \(x\),后继点为 \(y\),出度减当前松弛次数为 \(cnt\),转移方程为:
用 \(\text{dijkstra}\) 实现转移即可。
CF1842D Tenzing and His Animal Friends
从人 \(n\) 开始往外拓,假设一开始除 \(n\) 外所有人都上,并设与第 \(i\) 个人绑定的(前驱)人的集合为 \(S\) ,第 \(i\) 个人从开始到不能参加经过的时间为 \(d_i\) ,\(t_{i,j}\) 表示 \(i,j\) 两人单人最多待的时间。则:
本质上是求 \(n\) 到每个点的最短路。
[ARC150C] Path and Subsequence
设 \(d_x\) 表示从 \(1\) 开始到 \(x\) 的路径上与 \(B\) 匹配数最少的路径的匹配数。答案便是 \(d_n\) 是否等于 \(K\)。用 \(\text{dijkstra}\) 实现转移。
7.11
图联通
7.12
CF1834E MEX of LCM
\(\text{LCM}\) 一旦变化就是指数级增长,答案上界在 \(n \log n\) 级别,用st表或倍增暴力找出所有 \(\text{lcm}\) 即可。(啊啊啊啊,越界了越到另一个数组里导致值诡异突变啊啊啊啊啊啊啊)
7.13
CF1838E Count Supersequences
一开始像能否正着直接求,枚举 \(a_n\) 在第 \(i\) 个位置,\(a\) 中每一项在 \(b\) 中都位于第一次匹配上的位置,可以得到:
本来想递推式矩阵加速,发现不太行,通项也不好求,后来在题解区发现其实也是可以做的。
考虑反着做,求不匹配的方案数,设已经匹配到第 \(i\) 位,答案即为:
7.14
后来补上的网络流
7.15
CF1770C Koxia and Number Theory
指定模数 \(p\),发现在模 \(p\) 意义下的每一类里都至少有 \(2\) 个元素,那么无论 \(x\) 为什么,\(a\) 中每个数加 \(x\) 后必然有两个数都被 \(p\) 整除。\(p\) 不超过 $\left \lceil \frac{n}{2} \right \rceil $,枚举即可。
CF1771D Hossam and (sub-)palindromic tree
序列上直接区间 \(\text{dp}\),对应到树上是短链转移到长链,预处理出每条链由哪些短链转移过来,\(\text{dp}\) 转移采用记搜写法,转移十分方便。
CF1763F Edge Queries
翻译怎么又锅了,一开始还以为是仙人掌
想边双,由于走的是简单路径,还要考虑点是否为割点。而且jimmywang说过,点双的限制比边双紧。于是干脆求点双,建圆方树,方点上赋点双里的边数(如果只有一条边就为 \(0\)),圆点上赋 \(0\),直接转化为树上路径长。至于如何判断一条边在哪个点双里,用 \(\text{set}\) 维护。