SD2026 二轮省集
只想证明我存在的意义。
upd:标星的表示要补但没补的,其他没标的学了知识点或者我心情好了再做()
\(\text{day0}\)
睡了一上午,然后下午坐车到了平邑。出车站的时候突然有很大感触,原来真的已经过了一整年了吗,去年这个时候对未来是多么憧憬。
到酒店看了眼房间,报了到就去试机了,pyyz 依旧巨难用老爷机,vscode 装了一半突然想起来 cph 用不了,但是装都装了,devc 的运行好像也有点问题,于是决定使用 vscode 手动编译。
试机赛还挺有意思的,配电脑的时候顺带把两题暴力打了试验手感,观察了一会 A,左侧同学使用豆包严肃通过,听了下做法,移项之后只需要 check 小数部分是否均匀分布,这个很困难吗。看了看 T2,发现交换一下维度,就大概能得到一个可做的东西,然后对着这玩意调了半天,发现转移顺序还是有问题,然后没时间了,严肃返回酒店。
\(\text{day1}\)
\(60 + 60 + 0 = 120\)
被强制拖到很晚才睡,然后半夜被蚊子击杀了,为啥密闭房间内会刷新这么多蚊子。
吃完饭晚了一点到机房。开 T1 第一遍没看懂,想了一会感觉挺复杂的,看了眼 T3 不想读了,然后转头做 T2,\(1-n\) 的排列是简单的,然后有重复的升序去一下重就好了,然后感觉这个很好扩展到排列,改了下状态加两维枚举就能过排列了,优化一下得到 \(O(n^2)\),此时已经快一个小时了,我去今天咋这么顺利。编了一下非排列的做法,感觉细节很多,写了下正确性还有问题,看到 T1 像是过了一车人的样子,转头看 T1。原来 T1 可以随便改边,那只会把一棵树全拿或者合并两棵树,两棵树的合并细节有点多,考虑环长一样的两棵树只需要合并一次,但是环长不一样的好像不能单纯的合并一次,感觉是 \(\frac{l}{\gcd(l,l')}\) 的样子,并且环长只有 \(\sqrt n\) 个,感觉这已经是 \(O(n^2)\) 的做法了,先写了,然后调了很久很久,发现是太久没有做这方面东西了,哎我怎么还没复建成功。最后 40min 写完了,随机改了改参数获得 \(60\) 分,然后没时间了,遗憾下播。
T1
给定基环树森林,每一时刻所有点会向其父亲走一步,定义一棵树的代价为,某时刻处在同一个点上的点的最大个数,对于所有 \(k \in [1,n]\),求出原图修改至多 \(k\) 条边,所有树的最大值。
\(1 \le n \le 10^5\),1GB,3s
太久没做这种题了,感觉脑子完全不在线的样子。
先让我们编一个 \(O(n^3)\) 的做法,不难发现改边的决策等于于:
-
把一棵树自己合并,形成一个自环,可以拿到子树内的所有点。
-
把两棵树合并到其中一个的环上,具体怎么合并暂时不讨论。
假如我们能够知道这些的结果,那么该如何统计答案呢?能够发现,我们不妨钦定一个环作为答案环,然后将其他所有环合并到这个环上,这样一定不劣于以其他任意顺序合并这些环,因为按照其他环长不会使得答案更大。对于最后形成自环的,我们取 \(\text{siz}\) 前 \(k\) 大即可。
第一个合并显然是简单的,我们只考虑第二种合并。
考虑一个 \(l=2\) 和一个 \(l' = 3\) 的环,一开始我们可能猜测 \(l'=3\) 的环可以任意合并到 \(l=2\) 的环上,答案就是最大值相加,但是这样显然有问题,因为每次向右平移一个不是循环右移,因此我们需要枚举 \(l'=3\) 上的每一个点作为开头,并且进行染色,得到答案后就可以直接取 \(\max\) 和 \(l=2\) 合并了,每次两个环 \(O(n^2)\),每次搜索 \(O(n)\),复杂度 \(O(n^3)\)。
考虑优化,每次把环上所有点作为起点跑太慢了,我们考虑每次右移之后的变化量,不难发现只需要修改两棵子树,暴力地把这两棵子树的点修改了即可,然后还是可以任意合并,均摊少一个 \(n\),现在我们就有 \(O(n^2)\) 的做法了。
进一步地,我们发现 \(\sum \limits_{i=1}^m l_i = n\),那么本质不同的环长只有 \(\sqrt n\) 种,于是我们只需要按照环长枚举,求把某个环合并到环长为 \(L\) 的环的贡献,统计答案时对于某个环长 \(L\) 先选一个环长为 \(L\) 的树再取前 \(k-1\) 大即可,复杂度 \(O(n\sqrt n)\),不写拍子真难调吧。
记得判二元环。
T2
给定一个长 \(n\) 的序列,可以进行若干次操作,每次选定 \([l,r]\),记 \(k = \max \limits_{i=l}^r a_i\),令 \(p \in [l,r],a_p \gets k\),求最终局面数。
\(1 \le n \le 5\times 10^3\),\(A\) 性质保证 \(a\) 是个排列,\(B\) 性质保证 \(a\) 单调不降。
A 性质是 AT_agc058_b。
哎哎哎我怎么傻了,加一维就可以容斥了啊,场上在干什么,推广到非排列应该很自然的吧。
挨个包来看,对于 \(AB\) 性质,发现操作等价于一个数可以选择 \(\le i\) 任意长度的区间放置,从而影响最终序列,于是我们设 \(f_i\) 表示当前扩展到了 \(i\) 位置的方案,暴力转移即可,复杂度 \(O(n^2)\)。
对于 \(B\) 性质,我们考虑直接对序列去重,连续几个相邻数只需要在最后一个位置统计贡献,同上做即可。
然后进一步地,我们来看排列,发现其实就是多了个我们可以向右扩展,并且扩展是有限度的,记左边极长最后一个 \(\le a_i\) 的位置为 \(L_i\),\(R_i\) 同理。那么我们只能在 \([L_i,R_i]\) 选择一段子区间转移,同上转移即可,暴力复杂度 \(O(n^3)\),前缀和优化一下 \(O(n^2)\)。
然后来考虑非排列,现在选择和最终局面不是双射了,怎么去掉相同数的重复贡献。不难发现我们只对于最终局面的每个极长连续段在最后一个位置统计答案即可,那么我们就需要记录上个相同位置的 dp 值,于是设 \(f_{i,j}\) 表示用到第 \(i\) 个数,扩展到第 \(j\) 个位置了,考虑令 \(k\) 为上一个 \(a_i\) 的位置,我们我们只需要容斥掉 \((k,i)\) 之间不选的代价,即 \(f_{k,*}\),前提是所有区间都是合法的。
这里这个区间合法有一点细节,不难发现,如果区间 \([k,a_i]\) 合法,那么 \(L_k = L_i,R_k = R_i\),这个不难证明,直接判 \(L,R\) 是否相同即可。
然后转移大概步骤就是先拿不选的贡献,然后在 \([L_i,R_i]\) 内继承每个点作为左端点的贡献,容斥掉上一个相同位置的贡献就行了,直接做是 \(O(n^3)\) 的,前缀和优化做到 \(O(n^2)\)。
看了看郝队的代码,大概是设 \(f_{i,j}\) 表示 \(i\) 位置被 \(a_j\) 覆盖的方案,转移找到每个 \(j\) 的最长转移位置,容斥掉上一个相同的 \(j\) 即可,更好写一点。
T3
给定一个长 \(360\) 的圆环,和一个可重集 \(P\),一次操作可以按照一条直径或者一条半径切,求切出至少包含 \(P\) 的集合的最小次数并给出方案。
\(1 \le n \le 16\)。
感觉好像并不是很难的样子。
\(n\) 很小考虑状压,先把不用直径判掉,然后我们以一条直径为中心展开,这样就可以考虑每个元素划分到哪个集合内。
那么,我们就需要找出一种填数的顺序,使得我们能尽量多的使用直径,不妨先考虑 \(\sum q_i = 360\)。
对于当前两集合填数的情况,显然两侧和相等时可以把两条半径换成一条直径,那么我们就可以依次设计 dp,\(f_{i,S}\) 表示左边填到了 \(i\),用了 \(S\) 里面的数,最多的直径使用条数,然后暴力转移即可,复杂度 \(O(180n2^n)\)。
填完了之后,由于两侧都满了,那么我们显然就可以找到一种 \(n-1-f_{\max}\) 的放置方法。
对于 \(\sum q_i \neq 360\) 的情况,假设我们当前有一种填数的方案,左右两部分剩了两个空位,将这两个空位也视作我们原集合的数,那么我们还要决策这两个数能否匹配,这太复杂了。
这里有结论是,我们把两个空位放到最后一定不劣,考虑一点感性理解:
- 显然我们可以将存在问题的匹配放到最后一组来做,那么最坏情况下是这样的(可能?):

- 忽略他为什么是方的。发现这种情况下我们才需要空格去占位,但是这种情况下我们可以将两个红色块放到一起,和最优方案的次数是相同的,因此该性质成立。
然后我们就接着之前的 dp 做就好了,只不过我们这里的放置数变成了 \(n+1 + [S_1 + S_2 = 360] - f_{\max} - [S_1 = 180] - [S_2 = 180]\),加 \([S_1 + S_2 = 360]\) 是如果 \(\sum q_i = 360\),那么在 \(f\) 中多算了后面两个情况,这里和代码实现保持一致。
复杂度 \(O(360n2^n)\),为啥我跑这么慢。
世界是随机的。
世界是连续的。
世界是不公平的。
\(\text{day2}\)
\(100 + 5 + 15 =120\)
开题,T1 好像就是数三元环的 \(\max\),哦还可以数每个点的邻域,三元环直接硬做可以 \(O(n\sqrt n)\),哎怎么 \(n \le 10^7\)。大概看了一遍 T2,T3 发现好像都是不太擅长的样子,回头做 T1。
推了推发现每个点好像取最大边和次大边的三元环就行了?列了一堆不等式,感觉能证出来,然后开始写,写完发现挂了一万个点,此时刚一个小时。开始随机 debug,一直觉得是做法有 corner 没考虑到,三个小时的时候发现哈希乘 2e7 的时候忘开 ll 了,改完过了,我真没招了。然后拼了几个暴力,哎我 T2 \(O(ans\log n)\) 怎么死掉了,哎我无解怎么判错了,哎无解怎么判啊。
T1
给定一个 \(2n\) 个点,\(n\) 条带权边的无向图,请你从中选出若干条边,使其任意两条至少有一个公共点,求选择方案的最大值。
\(1 \le n \le 10^7\)。
不难发现选择方案要么是一个点的邻域,要么是一个三元环,邻域显然是简单的,三元环可以类似三元环计数的办法,找到每个三元环再取 \(\max\),复杂度 \(O(n\sqrt n)\)。
题解区怎么全到根号就结束了,这题能做线性的。猜测一些结论,对于一个点,取其最大和次大的边,那么我们断言,最大和次大边可能组成的三元环一定是这个点三元环的最优决策。
证明考虑,如果存在一个三元环,我们选的是最大和非次大的边权,可以据此列出不等式,由于一个三元环可以被这三个点都数到,于是这三个点都不能选次大的边,于是可以据此列出不等式组。简单推导可以发现出现了矛盾,一定存在一个点选择邻域不劣于选这个三元环,然后的证。
于是我们只需要 check \(O(n)\) 个三元环,复杂度 \(O(n)\),代码很好写。
T2
给定一个序列,一次操作定义为选择一个位置 \(-k\),其余位置 \(+t\),求最少多少次操作可以使得最终序列非正。
\(1 \le n \le 10^6,0 \le t,k \le 10^9,-10^{18} \le a_i \le 10^9\)。
很厉害的题。
考虑令 \(k \gets k+t\),然后每次操作等价于先进行全局加 \(t\),每次选一个位置减去 \(k\),这让我们的判定更简单一点。
先把 \(k=0\) 和 \(t=0\) 判掉。
对于一个操作次数是否合法,不妨记其为 \(x\),即判定 \(x \ge \sum \lceil \frac{a_i + xt}{k} \rceil\),这个暴力可以做到 \(O(n)\)。
然后尝试二分操作次数,发现这东西并没有单调性,因为操作过多可能导致小数变大不合法。
于是我们对原序列按照从大到小排序,考虑找到最大的 \(p\) 使得 \(k > pt\),记其为 \(n'\),不难发现如果操作了前 \(n'+1\) 个数,那么有 \(k \le n't\),我们的总和是增加的,所以并不优。
然后我们发现这个东西还是不能二分,因为前 \(n'\) 个数中还是可能会有操作多了的情况。但是有一个很牛的观察,对于一种操作 \(p\) 次的合法方案,\(p+n'\) 次一定也是合法的,因为前 \(n'\) 个数整体变小了(此处没有管 \(> n'\) 的数,后面会写的),所以,每一个 \(\bmod n'\) 的等价类是具有单调性的。
因此,一种暴力做法是我们可以对这 \(n'\) 个等价类二分,复杂度 \(O(n^2\log n)\)。但这还是太慢了。
一个很牛的技巧,我们把 \(n'\) 个余数随机打乱,假设当前我们已经有一个最小解,加入一个新等价类时,我们只需要 check 这个等价类小于当前最小解的最大数是否合法(每个等价类的合法性是独立的),如果可以再二分,显然这样一定会得到一个更优解,那么当我们随机取余数时,当前取了 \(i\) 个余数,那么第 \(i\) 个余数就有 \(\frac{1}{i}\) 的概率成为当前最优解,因此复杂度为 \(\sum \limits_{i=1}^n \frac{1}{i} = O(log n)\),因此把 \(\log\) 拿出来了,复杂度 \(O(n^2 + n\log n\log V)\)。
然后发现我们的瓶颈在于 check 是否存在合法解太慢了,于是我们考虑优化判定的式子,先二分出最后一个 \(a_i + xt \ge 0\) 的位置,然后前面等价于把 \(\frac{a_i}{k}\) 和 \(\frac{xt}{k}\) 拼起来,看是否加 \(1\) 的上取整即可,这部分容易用主席树做到 \(O(\log V)\),于是总复杂度变成 \(O(n\log V + \log n\log^2 V)\),可以通过。
记得判掉 \(k=0,t=0\),对于 \(>n'\) 位置的合法性只需要再最后判断答案是否合法就好了,在 check 判断会导致判断小于当前最小解的最大值不合法。
注意哪怕是负数也要计算上取整值,具体可以先加一个大数再减回来,注意下标到 \(2\times 10^9\),不要爆 ll 了。
T3
给定一个 \(R \times C\) 的 \(01\) 矩阵,平面是由若干该矩阵复制而成,每次询问两点能否四联通。
补了,感谢 lldxjw 推荐。
很像实数线性基啊,高维是不是也可以这么做。
考虑一个联通块如果是有限的,那么其大小显然不超过 \(RC\) 的,反之肯定会搜到相同点,因此我们可以对矩阵循环搜索找出每个联通块是否有限。
判定两个点相互可达的话,那么就是他们所在的矩形相互平移可达,并且同一矩形内所属相同联通块,后者显然是好判断的,考虑怎么判断矩形平移可达。
发现坐标值域很大,而且只需要判断连通性,那么我们可以往基的那方面想,类似 P4151,对于一个无向图,我们可以通过建生成树跑环得到一组基,而这组基可以表示无向图上所有路径的权。我们把矩形变成一个无向图,相似的把所有环跑出来,然后只需要看这些环能否表示出两点坐标差。
这里的每一个环都是一个二维向量,对于一对向量 \(\{a,b\}\),用 \(\{a + kb,b\}\) 显然也可以表示出他们所能表示出的全部向量,那么我们就完全可以把所有向量消成 \(\{(a,b),(0,c)\}\) 的形式,然后判断这组基能否表示即可,这个过程就很像线性基了,每次 \(O(1)\) 判断,复杂度 \(O(RC + q)\)。
已经 day4 了,我还是没写这个东西,前面几个题还是没那么难的,先把链接挂上来。
P9170 边重定向 trick 【UNR #2】黎明前的巧克力 上个题 gemini P5577
\(\text{day3}\)
\(100 + 7 + 60 =167\)
终于在比赛开始之前赶到机房了。
T1 随机瞪一下,\(n\) 是偶数肯定前后放就做完了,只需要考虑奇数,而 \(>3\) 的奇数可以前后放变成奇数情况,然后是不是 \(122112\) 这种构造就完了,小样例对完了,大样例被卡掉了,发现这种构造对于 \(>2\) 个奇数并不成立。然后开始随机排列,把问题转化成了 [1,n] 之间的数,每次选三个,使得 \(a+b=c\),要求最后选空,求方案,手玩了形如 \(n=3,n=12,n=15,n=48,n=51\),总结不出什么规律,然后同学玩出了什么东西,哦原来大样例给了构造方案吗/jk
把构造方案搞上去就做完了,T2 对于题意转化猜了若干结论,比如最大独立集一定大于等于和的一半,判断是否等于只需要 check \(f_{i,0},f_{i,1}\) 是否相等,想了半天也没找到合适的 dp 方法,打了暴力做 T3。发现暴力有 \(40\) 分,写完之后发现高度全相同更好写,写了若干时间,在比赛结束前 2min 完成,获得 60 分,然后赛后得知去掉高度的特判可以获得 \(80\) 分/jk
T1
给定 \(n\) 块,共有 \(k\) 种颜色的方块,给出一种重排后的序列,使得每种颜色下标和的平均数恰好为 \(\frac{n+1}{2}\),不取整。
不难发现,对于一种出现次数为偶数的颜色,在开头和结尾插入即可,于是我们只需要讨论出现次数为奇数的颜色。
还有一点细节,因为是 \(\frac{n+1}{2}\),所以当 \(n\) 为偶数的时候 \(\frac{n+1}{2}\) 一定为小数,而次数如果有出现次数为奇数的颜色的话,其下标和不可能为负数,所以此时不合法。于是出现次数为的奇数的颜色只有奇数个。
接下来我们只讨论出现次数为奇数的数,记其个数为 \(n'\),那么,对于出现次数 \(>3\) 的数,仍然可以在开头和结尾放置,于是我们只需要考虑一堆 \(3\) 怎么拼起来符合条件了。
后面就是对脑电波了吧,大概能想到可以分成三组,然后随机顺序排列一下,这里给出一种构造:
注意特判掉有一个或多个 \(1\) 的情况,然后把之前的构造拼到前后缀上就做完了。
如果你的出题人提供了大样例并提供了 .ans,上述对脑电波过程可以观察大样例得到。
T2
给定一个序列,每个位置有取值集合 \(A_i\),保证 \(A_i\) 内元素 \(\le m\),求多少子序列是“极好的”,“极好的”定义为其不存在一个子区间的最大独立集值等于这个子区间值的一半。
\(1 \le n \le 200,1 \le m \le 19\)
更亲民的题解:CTT 2023 D3T3 黄焖鸡 题解
牛完了吧这题。
对于这种类似零和的限制做转化,类似括号序列,我们令选为加,不选减,那么一个区间的最大独立集为 \(0\) 代表这个区间不合法,我们先考虑怎么对每个前缀 check 是否合法:
设 \(a,b\) 分别为结尾任意,结尾不选的值,那么其每次有转移 \(a' \gets \max(b+x,a-x),b' \gets \max(a,b) - x\),那么不合法当且仅当 \(a=0\),然后我们推几个性质:
-
首先任意时刻 \(a+b \ge 0\),考虑如果出现一组和为负数的独立集,那么我们翻转一下选和不选,则最差可以将 \(a+b\) 取反,而取反后是非负数一定更优,所以 \(a+b \ge 0\)。
-
\(a \ge b\)
-
如果在某个时刻 \(a+b > 0\),那么后面全部满足 \(a+b > 0\),考虑把后面加数的过程变成往后面拼一整个序列,由于后半部分的序列也满足 \(a+b \ge 0\),两个拼起来就满足 \(a+b > 0\)。
由性质 3 可以得出,如果出现 \(a+b > 0\),由于 \(a\ge b\),所以 \(a > 0\),此后一直合法,所以只有 \(a+b = 0\) 的序列是需要考虑的。
那么现在我们就可以将状态更新为 \((a,-a)\),每次转移到 \((\max(x-a,a-x),a-x)\),然后进行分类讨论:
-
\(x < a\),那么新的二元组为 \((a-x,a-x)\),\(a+b>0\),后面始终合法,不需要考虑。
-
\(x = a\),新的二元组为 \((0,0)\),此时这个前缀不合法,整个序列不合法。
-
\(x > a\) 新的二元组为 \((x-a,a-x)\),此时 \(a+b = 0\),所以还需要考虑,并且注意到新的二元组等价于将 \(a \to x-a\)。
进而,因为每次相当于加上新的数并将原来的数取反,那么等价于数组 \(s_i = a_i - s_i\),我们只需要判定 \(s_i\) 即可,前缀不合法当且仅当第一个 \(s_i=0\) 之前所有 \(s_i > 0\)。
这里补充一点,怎么刻画这个判定条件,不难发现 \(s_i\) 的含义是交错和,那为什么前面出现 \(s_i < 0\) 后面就一定合法呢。因为这只是交错和,并不是最大独立集,前面出现 \(s_i < 0\) 就说明已经合法了,后面由于交错和不一定最优才导致 \(s_i = 0\),所以前面不能出现 \(s_i < 0\)。
我们据此设计 dp,由于我们前面只考虑前缀,还要考虑每个前缀的后缀,由于每次 \(a \gets x-a\),所以 \(a\) 的值域不超过 \(m\),因此我们暴力状压每个 \(a\) 值是否存在即可,每次向后添加一个数。
注意到添加数是取反后加一个数,于是我们可以处理状态 \(S\) 的翻转 \(rev_S\),每次由 \(S\) 转移到 rev[S]>>(m-x) 即可,此处的 \(m\) 是 \(m+1\),具体原因是每次还要在最后添加一位 \(0\),所以总共有 \(m+1\) 个数。
下面 \(m\) 还是 \(m+1\),写出刚才的转移(复制开头的题解):
if(v[i][x]&&(j>>x&1^1)) ad(f[i][1<<x|(R[j]>>(m-x))],f[i-1][j]);
if(v[i][x]&&(j>>x&1^1)) ad(f[i][R[j+1]>>(m-x)],f[i-1][j]);//一个东西,和上面等价
第一个转移 |1<<x 的原因还是最开始添加的 \(0\) 翻转之后变成了 \(x\)。
暴力对这个 dp 转移可以做到 \(O(nm2^m)\),其实已经可以通过了,但是还可以更优。
考虑 R[j+1]>>(m-x) 的等价类,发现是翻转后所有的高位都不重要了,可以随便选,于是就是 \(j\) 的前 \([1,m-x)\) 可以随便选。
我们每次对前面无限制的跑一个高维和状物,每次就只需要枚举 \(2^{x-1}\),而 \(\sum \limits_{x=1}^m 2^{x-1} = 2^m\),总复杂度 \(O(n2^m)\)。
很牛啊,这题启发我们可以对于零和状物做类似折线图的变化,寻找一些特殊性质,dp 转移部分考虑实际有效转移和冗余转移是否是连续的,如果是连续的,那么可以考虑是否可以通过前后缀和之类的东西优化。
T3
数轴上 \(X_i\) 有高 \(H_i\) 的 \(n\) 个建筑物,有连接 \(L_i\) 和 \(R_i\) 的高 \(Y_i\) 的桥,保证桥与起点终点一定高度有交,如果桥和中途经过的建筑物高度有交,那么也可以上下,建筑物可以向上走,桥上可以横着走,求从 \(S\) 到 \(T\) 的最短路,或判断无解。
\(1 \le n,m \le 10^5\),性质 \(A,B\) 分别为 \(S=1,T=n\) 和所有建筑高度相同。
暴力不写了,逐个性质来看。
\(A,B\) 性质
显然我们此时不会走回头路,如果有走回头路的情况,那么完全可以走回头路与转点建筑的交点,可以省去回头的路段,显然更优。
所以我们横向移动的总长度就是 \(X_n - X-1\),接下来只需要考虑纵向移动即可。不难想到记录上每个桥时的最短位移,记作 \(d_i\),那么对于每个新增的桥,我们更新其 \(d_i\):
此处 \(S\) 是到当前建筑仍然未结束或恰好结束的桥。把绝对值拆开线段树维护一下即可。
\(A\) 性质
哎我们把 \(A,B\) 性质对 \(B\) 性质的特判删掉发现直接通过了 \(A\) 性质。
来考虑一点性质:
-
如果对于一个高桥和一堆低桥,低桥首尾相接,且末尾与高桥相接,那么我们此时选高桥一定不劣,因为中途走低桥的过程中可能会不停上下,总花费不少于高桥,于是我们对于相同的路径,会尽可能的走高桥。
-
进一步地考虑,基于 \(A,B\) 性质的做法,我们只在一个桥加入的时候计算其最短值,换句话讲,我们一定不会在两个桥中间做桥的切换。因为保证了桥的开头结尾与建筑物一定有交,所以如果要在中间切换到低桥会更优,那么低桥及其延伸路径一定会经过高桥的终点,否则就不是更优路径。所以我们一定会在至少一个桥的起点和终点上或下。
由上,不妨记一个桥的起始点和终止点为关键点,每次换桥一定会经过至少一个关键点,于是我们只需要找到每个关键点下面第一个交点,连边跑最短路即可,边数是 \(O(m)\) 级别的。
因此由于一个桥的开头和结尾一定与建筑有交,所以 \(B\) 性质其实是无用的。
正解
现在我们需要考虑 \(S,T\) 了,那么我们就有可能走回头路,并且能够发现走回头路的原因是为了上高桥,于是,我们就可以进一步地猜测:
我们只需要找到 \(S,T\) 最近的上桥的点,能够让他们走最少的回头路到达高桥,上了高桥之后的分析与之前是相同的。
于是,我们只需要额外记录每个桥上距离 \(S\) 左右最近的点,距离 \(T\) 左右最近的点,包括其起点终点,每个桥维护 \(6\) 个点即可,边数还是 \(O(m)\) 的,可以通过。
具体实现时向右扫描线维护最近点连边即可。
P4747
给定一个排列,\(q\) 次询问,每次询问包含区间 \([l,r]\) 的最小“区间”,“区间”的定义是排序后数字连续的区间。
\(1 \le n \le 10^5\)。
简单题吧。
先来一点,不难发现有交“区间”的并还是“区间”,两个“区间”的交还是“区间”,然后就可以暴力 \(\text{chkmn}\) 了。
考虑维护极大的数字连续区间是经典的,线段树维护最小值位置即可,然后我们对右端点从后向前扫描,每次左边每个位置能取到的最小右端点,发现这样就确定了一端,反过来再做一遍就好了。
AT_agc061_d
给定 \(n,m\) 和矩形 \(A_{n,m}\),要求构造两个严格递增的序列 \(X_i,Y_i\),使得 \(\max |X_iY_j - A_{i,j}|\) 最小,给出构造方案。
\(1 \le n,m \le 5,1 \le A_{i,j} \le 10^9,3s,1024M\)。
这题神了。
Hint:这题值域开到 \(10^{18}\) 做不了。
发现我们想不出什么可靠的方法,考虑调整法。首先二分答案每一组解的最小范围 \(D\),那么对于每一组数都有 \(A_{i,j} - D \le X_iY_j \le A_{i,j} + D\),不妨令 \(X_i \le Y_j\),初始 \(X_i =i,Y_i = 10^9+i+D\),显然此时 \(X_i\) 卡到了最小值,\(Y_i\) 卡到了最大值,但是此时的合法性我们不确定,需要调整。
有一种很巧妙的调整,对 \(X,Y\) 分别考虑:
-
当 \(X_iY_j < A_{i,j} - D\),显然需要增大,而 \(Y_j\) 已经是最大值了,所以 \(X_i = \lceil \frac{A_{i,j} -D}{Y_j} \rceil\)。
-
同理,当 \(X_iY_j > A_{i,j} + D\),由于 \(X_i\) 已经是最小值了,所以 \(Y_i = \lfloor \frac{A_{i,j}+D}{X_i} \rfloor\)。
-
当 \(X_i \le X_{i-1}\) 时,令 \(X_i = X_{i-1}+1\)。
-
当 \(Y_i \le Y_{i-1}\) 时,令 \(Y_{i-1} = Y_i-1\)。
总之调整的核心思想是 \(X,Y\) 各自卡到了最小和最大值,所以这样是具有正确性的。
至于复杂度,由于 \(X_i \le Y_i\),所以 \(X_i \le \sqrt{10^9 + D}\),对于 \(X_i\) 的调整次数不超过 \(n\sqrt{10^9 + D}\) 次,而每次调整 \(X_i\) 的时候,最坏情况是所有 \(Y_j\) 都变一次,所以复杂度 \(O(m)\),总复杂度 \(O(nm\sqrt V\log V)\)。
有时候最优化问题不妨考虑调整法,找到一种合适的调整方式再分析复杂度。
QOJ4217
给定一个包含 \(n\) 个点的竞赛图,你的任务是将图中所有的边染上颜色,可用的颜色共有14种。染色方案必须满足图中不存在任何一条长度为2的路径 \(i \to j \to k\),使得边 \((i,j)\) 的颜色与边 \((j,k)\) 的颜色相同。
\(1 \le n \le 3000\)。
有点诡异了,感觉前两种做法更具有启发性。
一.位运算构造:考虑如果对于 \(u<v\) 都有 \(u \to v\) 怎么做,由于颜色数接近 \(\log\),可以考虑位运算构造,令两点之间边颜色为 \(\operatorname{highbit}(x \oplus y)\),这样为什么是对的?考虑三个点 \((x,y,z)\),如果 \(x \to y\) 和 \(y \to z\) 具有相同颜色,那么说明 \(x,z\) 具有相同的最高位,那就有 \(z>y\) 了,所以不成立。这样对于全序图只需要 \(\log\) 种颜色,但是原图可能不满足上述性质,需要对 \(u<v,u\to v\) 和 \(u>v,u \to v\) 分别跑,总共 \(2\log\) 种颜色。
二.分治构造:考虑分治,仍然考虑全序图,对于区间 \([l,mid]\) 和 \((mid,r]\) 我们让左边向右边连一种颜色的边,分治树上同一层连一种颜色,这样只需要 \(\log\) 种颜色,总共仍需要 \(2\log\) 种。
三.集合型构造:注意到 \(\binom{14}{7} > 3000\),转化一下题意,我们给每个点一个大小为 \(7\) 的集合,题意等价于对于一条边 \(x \to y\),不存在 \(a \in S_x \wedge a \in S_y\),我们把所有大小为 \(7\) 的集合拿出来暴力分配即可。
QOJ4218 感觉还可以在看看,没有理解很透彻。
P5115 对串串没什么理解,看起来是好题,先不写了,复建完串串再写。
P4118 末日三问,典成啥了,线段树维护凸包,原来分块线段树维护困难信息是这里的,太难写了,以后再说。
\(\text{day4}\)
\(100 + 20 + 10 = 130\)
有点搞笑了。
哎我去 T1 怎么发了个论文,研读论文,发现前两个性质分别是莫队和回滚莫队,大胆猜测正解做法是这个在线莫队,2h 之后发现好像没有关联,感觉优化这个东西的复杂度只能找出包含关系,感觉论文给了复杂度证明这个应该很对,写了找随便一个包含的就过了?我线段树都敲一半了。然后坐牢 3h,大概就是 T2,T3 换着想,一直在对着 T2 的爆搜卡常,最后十分钟卡过了 \(20\) 分,感觉完全没有 dp 可以刻画这个东西。
然后听到有人说 T2 网络流突然发现好像会了,转成最小点覆盖然后相邻邻域视作一对 01 就可以暴力了,这个东西完全没必要满的 \(O(n^{4.5})\),每次加边就 \(O(n^{3.5})\) 了,最后几分钟问了 gemini T3 做法,发现就是对着 \(b_i = 2\) 的记状态记搜,怎么能过 \(75\),力竭了。
T1
使用 \(O(n\sqrt q)\) 次加入操作和 \(O(n)\) 次清空操作维护出 \(q\) 个均匀随机区间的信息。
场上写了求出每个区间任意一个包含的区间就过了,复杂度分析好像不是这样。
考虑按照 \(l_i\) 排序,那么最少重构就是 \(\text{LIS}\),因为随机序列下 \(\text{LIS}\) 的期望长度是 \(O(\sqrt n)\) 的,所以复杂度 \(O(n\sqrt q)\)。
*T2
称一个 \(n\times m\) 矩阵是好的当且仅当如果 \(d_{i,j} \le d_{p,q}\) 则 \(a_{i,j} \ge a_{p,q}\) 其中 \(d_{i,j} = |i-r|+|j-c|\)。给定矩阵 \(a\),你可以选取若干长度为 \(1\) 或者高度为 \(1\) 的矩形,将矩形内的元素对某个值取 \(\min\),问最少需要多少此操作可以把 \(a\) 变成好的。
\(n,m \le 160\).
哎怎么是网络流题,做过滚木个网络流怎么办。
考虑 \(r=1,c=1,a_{i,j} \le 2\) 时,我们只需要枚举左上角等否画出一个距离为 \(d\) 的范围,剩下的问题就是把一些 \(a_{i,j} = 2\) 变成 \(1\),这就是典型的网络流问题了,转成最小点覆盖做就好了。
对于 \(r=1,c=1\) 的情况,我们只需要把相邻的邻域视作刚才的 \(1,2\),直接做就好了,最后再拼起来,直接做复杂度是 \(O(n^{4.5})\) 的,考虑每次只需要固定左端点扩展右端点,不需要重复跑网络流,复杂度就是 \(O(n^{3.5})\) 的。
对于 \(r,c\) 的一般情况就是变成了四个方向,更麻烦一点。
T3
不是很懂怎么办。
数论专场,补题了,挂个链接,过几天肯定要学这东西。
P5451 CF1299E AT_arc127_f CF500G 未知来源题目 秋季限定生成树问题 【UER13】加密通信 AT_agc031_f
\(\text{day5}\)
?
复刻 NOIP2025 吗,没看 T2,T3,对着 T1 数数做了整场,最后和正解前半段是一样的,系数又有点问题。如果做整场 T2,结果会不会不一样呢。这真是 NOIP2025 吧。一定要加训数数。
*T1
*T2
T3
要忙死了,先把题记下来之后当好题选写做了。
CF1889D
给定 \(n\) 个栈,定义 \(f(i)\) 为:
- 如果栈 \(i\) 为空,那么返回 \(i\)。
- 否则,记栈顶为 \(a_i\),那么返回 \(f(a_i)\)。
对 \(i \in [1,n]\) 输出 \(f(i)\)。
\(1 \le n \le 10^5\)。
考虑所有栈都只有一个元素的时候,显然形成了一棵基环树,而走到环上的第一个点就是我们的终止点,因为走完一圈会回到这个点上。
扩展到每个栈有更多元素的时候,虽然看起来图并不规则,但是我们还是可以沿用上述方法,对于一个环,我们只需要其第一个点,所以说,我们只需要找到所有环删掉然后记忆化跑一下就好了。
复杂度 \(O(\sum k_i)\)。
QOJ16507 QOJ7530 弱化版 P3274 P10435 CF1456E 【UR #26】铁轨回收
\(\text{day6}\)
??
?我 T1 假了吗,不会这么简单吗,哎怎么只有 70,还要分讨 \(X\) 啊,这俩玩意能同时处理吗,随机写了点乱搞,加上暴力对最后一个位置修改就过了?然后开始坐牢了,到最后才看懂 T2 题意?我又没睡醒吗,在干啥。一定要手玩样例验证题意啊。
T1
给你一个数组 \(x_i\),让你将其中某一个数加上 \(X\),问所有前缀和均非负的非空区间数量最大值。
\(1 \le 5\times 10^5\),性质 \(X \ge 0\)。
check 每个数的最近位置第一想法肯定是暴力二分吧,但这是 \(O(n^2\log n)\) 的,拿折线图刻画这个过程,发现拿个栈维护每次弹出位置即可,暴力复杂度 \(O(n^2)\),获得 50 分。
考虑 \(X \ge 0\) 时,先说 \(O(n\log n)\),我们考虑枚举 \(+X\) 的分界线,只需要枚举每个位置到不加 \(X\) 的位置和 \(+X\) 的位置分别的最小位置,扫过去的时候更新一下就好了,这两个都可以二分找到。
\(O(n)\) 就是我们发现这个过程完全没有必要,正反两遍单调栈即可,获得 \(70\) 分。
对于 \(X < 0\) 的部分,考虑反过来扫,然后维护一个前缀集合的后缀 cov,这个是容易用 ODT 做的,怎么 \(O(n)\) 忘了,赛时乱搞过了,就不补了。
挂个 QOJ 链接。
T2
给定一棵树,每个点有权值范围 \([L_i,R_i]\),你可以选择若干关键点,使得 \(1\) 到每个叶子之间的关键点恰好形成长度为 \(k\) 的不上升子序列。
\(1 \le n \le 200,1 \le L_i,R_i \le 10^9,1 \le k \le 20\),特殊性质 \(L_i = 1,R_i = 10^9\)。
好题啊,拉插的 trick 没怎么写过。
难点是敢去写这个 dp,考虑 \(L_i = R_i\) 时怎么做,容易设出 \(f_{i,j,k}\) 表示以 \(i\) 为根的子树,最大值为 \(j\),关键点长度为 \(k\),转移很自然,大概就是分两个步骤,一个是合并子树,一个是决策自己是不是关键点。
显然可以前缀和优化,做到 \(O(nkV)\),对于 \(L_i \neq R_i\),每次决策自己时加个 \(R_i - L_i + 1\) 的系数即可。
我觉得有必要写一下链 \(L_i = 0,R_i = 10^9\) 怎么做,我确实在场上想了一会然后逆元写错了,先选 \(k\) 个数可重,可重集组合数是 \(\binom{V+k-1}{k}\),然后乘上选位置的系数和其他不选位置的系数 \(\binom{n}{k}\) 和 \(V^{n-k}\)。
后半部分没怎么见过,大部分可能都是抄袭题解。
之后考虑怎么优化这个 dp,我们写出转移式子:
我们不妨用一个同次的式子描述,记 \(f'_{u,j,k} = f'_{u,j-1,k} + f_{u,j,k}\):
考虑特殊性质 \(L_i = 1,R_i = 10^9\),也就是说,右半部分 \([L_i \le j \le R_i]\) 一定为 \(1\),剩余部分全是乘加运算。
我们换成一个关于 \(j\) 的函数 \(F_{u,k}\),具体的有 \(F_{u,k}(j) = f_{u,j,k}\),那么上式变成:
在叶子处,\(F_{u,k}\) 是常值函数,\(F'_{v,k}\) 是一次函数,因此,一个点的次数不超过 \(siz_u\)。
因此,我们可以维护 \(n\) 个点的点值,然后插出在 \(10^9\) 处的值就行了,复杂度 \(O(n^3k)\)。
对于一般的问题,我们考虑所有区间形成 \(O(n)\) 个小区间,每个小区间内同一个点的转移后面系数要么全 \(1\) 要么全 \(0\),就转化成了上一个问题,同样的做即可,对每个区间 \([x,y]\),取前 \(n\) 个数跑出点值,再插出 \(y\) 处的值,如果区间太小暴力算就行,然后做完这一个区间就可以将 dp 值当做下一个区间的初始值继续做。这里暴力拉插的话复杂度 \(O(n^4k)\),但是我们取的 \(n\) 个点坐标连续,那么可以优化到 \(O(n)\) 插值,复杂度 \(O(n^3k)\)。
我还没写,应该是这样的吧,抽时间写一下。
写完了,std 的写法还挺简单的,对每一个插的值跑一遍 dfs,然后过程中记录一下前缀和转移就行了,就是常数有点大。
T3
有一个 \(\text{DAG}\),从 \(1\) 到 \(n\),每个点有事件:
无事发生。
获得一个 \((a_i,b_i)\) 的卡片。
选择一张已有卡片,将 \(a_i \gets a_i + k\)。
选择一张已有卡片,将 \(b_i \gets b_i + k\)。
战力直接加 \(w\)。
在 \(n\) 点选择一个卡片使 \(a_i \gets a_i \times 10^9\),求 \(\sum a_ib_i + \sum w\) 的最大值。
\(1 \le n,V \le 200,1 \le m \le 2000,1 \le w \le 10^6\)。
复读题解。
第一个观察是,\(\times 10^9\) 会使得这张卡牌一定成为战力最大的,其他牌怎么加都加不到 \(10^9\)。
放到链上来讨论,变成序列问题,\(4\) 操作显然是弱的,暂且不讨论。
先考虑最后最大的那张牌,显然获得他的时候后面所有 \(2,3\) 操作都会加到他上面,那么这就形成了一个后缀。
扔掉这个后缀,我们考虑前面的问题。这时候就不好贪心了,因为 \(2,3\) 同时存在会带来后效性,我们考虑一个暴力 dp,设 \(f_{i,j,k,0/1}\) 表示前 \(i\) 个点,最大的 \(a\) 为 \(j\),最大的 \(b\) 为 \(k\),最大的 \(a,b\) 是否是同一个点。
转移是自然的,\(j,k\) 的上限是 \(O(nV)\) 的,那么这个 dp 复杂度就是 \(O(n^3V^2)\) 的。
然后就是这个题一个很厉害的结论,我们断言,\(j,k\) 中一定有一个不超过 \(V\),考虑证明:
-
假设当前存在一个 \(j,k\) 均大于 \(V\) 的状态,如果 \(a,b\) 最大值是同一个点,那么显然后面再取那个后缀贪心就是更劣的了,这种情况一定不会取到。
-
当 \(a,b\) 最大值不是同一个点时,发现这种情况一定不会存在,如果 \(a\) 最大值是先存在的,由于 \(b\) 最大值一定被操作过,才会出现 \(b > V\) 的情况,但是此时显然给 \(a\) 操作是更优的,所以这种情况不存在,因此上述结论是成立的。
所以我们就可以把其中一维降到 \(O(V)\),记得交换 \(a,b\) 再跑一遍,此时复杂度 \(O(n^2V^2)\),后文我们默认 \(a\) 是更小的那一维。
但是这样还是太不牛了,因为还有一维是 \(O(nV)\) 的,那我们能不能记录两维同一种值的信息,然后顺便维护出另外一维的贡献呢?
考虑之前的状态记录 \(O(nV)\) 那维的状态是干什么的,因为我们在加入牌时不知道后面他给其他牌带来的贡献是多少。那么,我们直接钦定他的最终状态是多少不就行了。
具体地,我们设 \(f_{i,j,k}\) 表示前 \(i\) 个点,为了补到钦定值还差 \(j\) 的 \(a\) 值,当前最大的 \(a\) 值为 \(k\)。
此时 \(2\) 操作就变成了一个类似还债的操作,\(3\) 的贡献也可以直接计算,\(1\) 操作时我们提前钦定加入的牌的最终 \(a\) 值。
这样,我们就把复杂度降到了 \(O(nV^2)\),放到 \(\text{DAG}\) 上 \(O(mV^2)\)。
还有一点小问题,对于提前钦定的那段后缀,我们要再对着反图跑一个 dp,具体的,令 \(g_{i,j}\) 表示 \(i \to n\) 的路径上,\(\sum a = j\),然后以 \(\sum b\) 为第一关键字,\(\sum ab + \sum w\) 为第二关键字的最大值,转移很自然,这部分复杂度 \(O(nmV)\)。
最后拼一下答案就行了,总复杂度 \(O(nmV + mV^2)\)。
\(\text{day7}\)
100 + 40 + 20 = 160
在不会写 \(\text{2-sat}\),T3 观察不出结论下的最高分数?
开场读完 T1 就开始写了,没多长的东西写了一万年,调了一堆错,中间还读错了一次题,幸好我开始就是 \(\log^2 n\) 的做法,随机改一下就行了。写完不到 1h,再 1h 拼了 T2 所有暴力包,发现后面就是线段树优化建图后 \(\text{2-sat}\),但是这俩玩意我一个都记不起来怎么写,去开了 T3,对着 \(O(n^2)\) 想了 1.5h 左右,没敢猜关键结论,只有 \(20\) 分,然后后面不知道干什么了?
T1 怎么全过了,T2 怎么才是签到,T3 这结论怎么被我叉过。
T1
坐标系内给定若干点,有若干横坐标位于 \([l_i,r_i]\),纵坐标为 \(v_i\) 的线段,所有点同时开始下落,下落速度相同,每个时刻如果有线段被点接触,那么线段连同所有与它相交的点一起删除,求每个点被删除的时间。
\(1 \le n \le 10^5\)。
考虑线段树上维护 set,插入所有线段后按照高度扫描,每次删除线段,复杂度 \(O(n\log^2 n)\),注意到每次删除的一定是排序后的后缀,拿个栈做即可,复杂度 \(O(n\log n)\)。
T2
给定 \(3n\) 个位置,\(q\) 个限制,每个限制形如 \([a,b],[c,d]\),要求要么 \([a,b]\) 内全为 \(0\),或者 \([c,d]\) 内全为 \(1\),报告无解或者给出 \(0\) 和 \(1\) 数量均不超过 \(2n\) 的合法方案。
\(1 \le n \le 3\times 10^4,1\le q \le 10^5,1 \le \sum n \le 10^6\)。
晚上重新学了一遍 \(\text{2-sat}\) 和线段树优化建图。
这才是签到吧,后面这个形式很 \(\text{2-sat}\),考虑如果区间退化成点怎么做。
不难发现,条件等价于 \(a \to c\) 连一条边,因为原条件是 \(a \vee \neg c\),那么这个 \(\text{2-sat}\) 一定不会无解(应该是吧,因为 \(a\) 和 \(\neg a\) 一定不在一个 \(\text{scc}\))。
肯定要进行缩点,一个简单的想法是对拓扑序上的一段前缀变 \(0\),一段后缀变 \(1\)(虽然这样已经可以在 OJ 上通过了),但是还是有几个 case。
比如存在一个很大的 \(\text{scc}\),其加上前后缀都会 \(> 2n\),但是此时是可能有解的,显然这个 \(\text{scc}\) 应该是 \(> n\) 的(可以简单反证一下),那么我们只需要取出这个 \(\text{scc}\) 可达的所有点变成 \(1\) 即可,但是如果他可达的点也 \(> 2n\) 呢,那我们对反图跑就好了,这样一定能得到一个最优解,判断是否合法即可。
然后变成两个区间线段树优化建图就好了,复杂度 \(O(n + q\log n)\)。
qoj 上有一万个 corner。
T3
给定一棵树,对每个 \(k \in [1,\lfloor \frac{n}{2} \rfloor]\),求出 \(k\) 对点匹配的最大边权和。
\(1 \le n \le 10^6\)。
猜不到结论完全无法进展啊,只会写一点关于结论的感性理解。
性质 \(1\):一般图最大权匹配的点集是增量的,所以记 \(S_k\) 为 \(k\) 对点匹配的点集,有 \(S_k \subseteq S_{k+1}\)。
性质 \(2\):对于树上两条不交路径 \((u_1,v_1)\),\((u_2,v_2)\),选择路径 \((u_1,v_2),(u_2,v_1)\) 是不劣的。
考虑 \((u_1,v_2)\) 与 \((u_2,v_1)\) 的交,显然其余部分覆盖了原路径,那么就多出来了交集部分的边权。
性质 \(3\):\(k\) 条路径交于一点,且这一点为点集的重心。
由于性质 \(2\),随意令一个点为根,不会出现任意一对点在子树内就匹配了,因为其显然可以与子树外的一对点交换使得答案更大,因此所有点交在一点,且这一点为最中心的位置,即点集在原树的带权重心。
我们首先考虑每次向点集内加点,由性质 \(3\),所有路径交在重心,而点集的重心是一对链的交,也是一条链。而进一步地能够发现,如果这条链还未退化,那么所有关键点一定位于其两端的子树内,并且点数相同。
由性质 \(3\),对于答案的统计只需要所有点到重心的距离之和,我们就不需要再求匹配了,找到最大距离和即可。
每次加入一条链的时候,我们找到链的两端在重心链上的投影,继续取交,就是新的重心的范围。
我们每次选择离重心最远的点,并跳到其对应的投影处,那么能够发现连续操作两次我们就得到了 \(S_{k+1}\),这个过程和找直径是类似的,连续两次我们就找到了一条直径。
但是这样太麻烦了,实现需要点分树之类的,复杂度是 \(O(n\log^2 n)\) 或者大常数 \(O(n\log n)\),难以通过。
关于动态维护重心,有性质是任意一个点集的重心一定在其按 \(\text{dfn}\) 排序后的第 \(\lfloor \frac{|S|}{2} \rfloor + 1\) 个点到根的路径上。
证明是简单的,考虑如果重心向非链方向偏移,那么至少会有一个子树包含整条链,这是一定不优的。
考虑把整个过程反过来,我们每次删离重心最远的点。
由于最初时点集是满足重心两边点集大小相等的,当我们剩余点数为偶数的时候,这个性质不改变,所以重心是不用变的,当剩余奇数个点时,我们就需要向关键点更多的那一边走,并把子树内多的且离的最近的点删掉。
然后我们需要讨论一下重心移动的方向:

-
向下跳时,先让重心向下走一步,到 \(\lfloor \frac{|S|}{2} \rfloor + 1\) 路径上的儿子位置,然后此时子树内的 \(\text{dfn}\) 最小和 \(\text{dfn}\) 最大关键点的 \(\text{LCA}\) 即我们可以跳到的最低位置,注意判断此时子树是否是偏大的那个,不然可能走过头。
-
向上跳时,也是类似的,我们只需要找到子树 \(\text{dfn}\) 区间外 \([R+1,n]\) 左侧第一个和 \([1,L-1]\) 右侧第一个关键点,取 \(\text{LCA}\) 就是我们要跳到的位置,由于我们只是跳到了一个最高点,下一步还需要再走到另一个偏大的子树内,所以这两步是可以反复进行的。
发现这样做的优点是什么,我们只需要动态维护到当前重心的最近点,不需要维护直径了。由于关键点只会落在重心两侧,所以我们每次移动重心时只需要修改两个区间的距离,复杂度就是小常数 \(O(n\log n)\)。
这题比较卡常,两次区间修改可以变成一次全局改一次区间改,拿个变量记,然后需要 \(\text{dfn}\) 序的 \(O(1)~\text{LCA}\),卡空间的话用 vector 就行了。
CF1805F2
给定一个非负整数数组 \(a_i\),初始长度为 \(n\),接下来将对该数组进行 \(n-1\) 次变换,每一次变换前记数组长度为 \(m\),则将数组 \(a\) 变为所有 \(\frac{m(m-1)}{2}\) 个形如 \(a_i + a_j (i \neq j)\) 中最小的 \(m-1\) 个,问最后剩下的数是多少。结果取模。
\(1 \le n \le 2\times 10^5\),简单版本 \(n \le 3000\)。
\(n \le 3000\) 是简单的,拿个堆每次调整一下,注意为了防止溢出我们每次把所有值减去最小值,最小值设为 \(0\),记录所有值的偏移量即可。
延续上述思路,发现 \(a_n\) 很可能是没用的,但是在比较极端的情况下是有用的,带上减去最小值的步骤,对于序列 \([0,a_2,a_3,\dots,a_n]\),如果 \(a_n\) 在一次操作后仍对序列有影响,那么肯定有 \(a_2 + a_3 > a_n\),不然 \(a_n\) 就被 \(a_3\) 替代了,所以序列一次后变为 \([0,a_3-a_2,\dots,a_n - a_2]\),再做一次就变成了 \([0,a_4 - a_3,\dots,a_n - a_3]\),而因为 \(a_2 + a_3 > a_n\),所以 \(2a_3 > a_n\),因此此时 \(a_n\) 至少减半,那么我们便知道,如果最后一个位置想在两次操作后仍然能对序列产生影响,那么序列极差至少减半。这个结论推广到任意 \(i\) 都是成立的。
所以,我们只需要保留 \(L = 2\log V\) 个数就好了,对于证明,对于前面 \(\le L\) 的位置,如果 \(a_2 + a_3 \le L\),那么我们就可以用前 \(L\) 个数推出最终答案,反之序列极差就会被减半,那么我们就可以视作 \(V \gets \frac{V}{2}\),即 \(L \gets L-2\),然后就可以归纳证明正确性。
对着这 \(L\) 个数跑 \(n\) 次操作即可,复杂度 \(O(n\log V\log \log V)\)。
CF1835E
有一个长 \(m+1\) 的键盘和需要打出的长 \(n\) 的字符串,初始不知道按键对应字符或者是否是删除键,按完了可以知道按键对应信息,求打出完整字符串的期望按键次数。
\(1 \le n \le 10^6,1\le m \le 10^3\)。
状态设计和延迟钦定的想法很牛。
发现 \(n\) 很大,\(m\) 很小,而我们打完一个字符是知道按键对应什么的,所以我们并不需要对整个 \(n\) 串跑,只需要对第一次出现的字符跑就好了,把 \(n\) 扔掉。
然后这个问题还是很困难,因为我们肯定不能记录当前有了哪些按键,于是考虑延迟钦定按键对应的什么,转移时乘个系数即可,考虑设 \(f_{i,j,0/1/2/3}\),表示到第 \(i\) 个字符,已知但还没有用的按键数量 \(j\),以及若干分类讨论:
-
\(0\) 表示当前打的全对,不知道退格键。
-
\(1\) 表示打错了,正在找退格键。
-
\(2\) 表示知道了退格键,但是还没考虑 \(j\) 个键中有没有想要的键。
-
\(3\) 表示知道了退格键,并且 \(j\) 个键中没有想要的。
这 \(4\) 个状态的设计很巧妙啊,尤其是作为中转状态的 \(2\),可以很好的使用延迟钦定,或许所有延迟钦定状态都可以这样设计(?)
太困了,转移明天写。
CF1806F2 比较牛的推结论过程,小掉了一会,等着明天补。
CF1801G 串串让我先摆一下。
CF2207H3 以后再说。
\(\text{day8}\)
\(61 + 35 + 25 = 121\)
是不是随便打一个非一般分数就赢了来着,我在干什么。做了一万年 T1,最后一个小时把暴力拼上了,然后发现 T3 \(80\) 可以随便做一下对完了,结果没时间写了。
能不能让我赢一次 /ll
T1
给定一个序列,\(A,B\) 两人可以轮流向内填数,初始已经加入了 \(q\) 个数,保证 \(q\) 是偶数,下一次由 \(A\) 放置,有两种规则,用 \(v\) 表示,如果 \(v=1\) 表示第一次放置后出现长 \(k\) 的 \(\text{LIS}\) 的获胜,\(v=0\) 表示失败,当一个人无法再放置时失败。
\(1 \le n,k \le 10^5\)。
思维难度递减。
显然要对于 \(v\) 分讨,记一个未放置的数 \(x\) 的 \(f_x\) 表示在前 \(q\) 个数的情况下加上 \(x\) 后以 \(x\) 为结尾的 \(\max \text{LIS}\),\(c_y\) 表示 \(f_x = y\) 的数量。
对于 \(v=0\) 的情况,我们对剩余数字个数讨论:
-
剩余个数为偶数时,显然取到 \(k\) 的人获胜,那么作为后手的 \(B\) 只需要等到 \(A\) 取到 \(k-1\) 时抢先拿到 \(k\),那么 \(A\) 就输了,那如果 \(k-1\) 后面没数了导致 \(B\) 没法拿到 \(k\) 了呢,显然此时等价于 \(A\) 选了一段无用的前缀,由于此时 \(A\) 在选空的情况失败,所以这样 \(A\) 一样必败。因此,我们发现,除非 \(A\) 第一步直接拿到 \(f_x = k\),否则 \(A\) 必败,那么选择方案就是 \(c_k\)。
-
剩余个数为奇数时,\(A,B\) 策略好像对调了,此时 \(A\) 删空后必胜,那么我们只要防止 \(B\) 拿到 \(f_x = k\) 即可。赛时的做法比较暴力,考虑枚举 \(A\) 选的每个位置,那么 \(A\) 获胜只需要 \(B\) 拿不到 \(k\) 或者 \(k\) 后没有可用数了,然后就做完了。
然后考虑 \(v=1\) 的情况,场上做了整场都没想明白:
-
题解写的 \(p\) 有点神秘了,考虑想一点最优策略,显然此时选到 \(k\) 必败,我们对 \(k-1\) 考虑。
-
假如当前剩余数为奇数,我们 \(A\) 沿用之前的策略,每次从后向前取,等着 \(B\) 拿到 \(k-2\) 时再取 \(k-1\),对这里这个策略分讨一下:
-
如果此时 \(k-2\) 和我们后面挂机的位置空了至少 \(2\) 个,那么我们显然可以通过选择和 \(k-2\) 挨着或者隔一个来控制剩余数的奇偶性,那么之后的局面就被我们控制了,此时我们必胜。
-
如果此时 \(k-2\) 和我们不空位置,那么此时 \(B\) 的决策同上是不优的,因为此时 \(B\) 在删空时必败。
-
如果 \(k-2\) 和我们空了一个位置,那我们把空的位置填上,然后变成了 \(B\) 先手,偶数个剩余数的情况,此时它再操作一步肯定不会出现 \(k-1\),那么它任意选一个都可以继续转化为剩奇数个数,\(A\) 先手的情况,因此这种情况下我们依旧必胜。
-
-
然后我们发现,如果剩余数有奇数个,那么先手必胜,那如果剩余数有偶数个呢。
-
类似的猜测,偶数时为什么不能删掉一个数后等价于奇数情况。其实是由于 \(k-1\) 的存在,连续的两个 \(f_x = k-1\) 可以删除任意奇偶性的后缀,所以大于等于两个 \(f_x = k-1\) 可以任意控制局面进入剩余奇数个数,\(A\) 先手的局面,此时一定必胜,而且我们只会在前两个 \(f_x = k-1\) 中选择一个,因此一定有解,方案数为 \(1\)。
-
进一步地,再 \(c_{k-1} \le 1\) 的情况下,我们无法控制奇偶性,那么此时剩余偶数个数任意选一个数之后的结果就不受影响了,后手一定会进入奇数局面从而必胜,所以此时先手必败。接下来我们考虑当前剩余奇数个数且 \(c_{k-1} \le 1\) 的情况:
-
对于 \(c_{k-1} = 1\),哪怕选择这个 \(k-1\) 也无法凑出 \(k\) 了,那么此时这个 \(k-1\) 和 \(k-2\) 没有本质区别,如果此时存在 \(\ge 2\) 个 \(k-2\),那么我们不能取到倒数第二个及以前的 \(k-2\),因为它会导致选择后后面的 \(k-2\) 和 \(k-1\) 等价于 \(k-1\),那么又进入剩偶数个数,偶数个 \(k-1\) 后手的局面,此时必败,所以我们最多只能取到最后一个 \(k-2\)。注意此时前面 \(f_x \le k-3\) 的数可以任意选,因为哪怕这一步选了前面数,\(B\) 会进入剩偶数个数,\(c_{k-1} \le 1\) 的局面,此时 \(B\) 必败,所以我们必胜。所以前面均可以取。
-
对于 \(c_{k-1} = 0\),我们再向前平移一个,如果选择了倒数第三个及以前的 \(k-2\) 会导致后面变成 \(k-1\),从而导致必败局面,所以我们最多只能选择两个 \(k-2\),前面仍然可以任选。
-
到这里就讨论完了,感觉难点是对万能构造的发现并且发现剩余个数为奇数的局面是必胜的。
我靠怎么写了这么长,蠢完了。
T2
\(\text{BEST}\) 定理。
*T3
树哈希,感觉很难写,鸽了。
\(\text{day 9}\)
\(60 + 16 + 16 = 92\)
输麻了。
开场做了 2h T1,编了很对的做法,每次合并三元环,环不够了就拆奇数点造环,然后一堆细节什么,写完发现只有 \(24\),发现随机地方写挂,改完过了 \(60\),哎我靠怎么死了,好像奇数点不能这么简单做,那我不懂啊,太复杂了。
转看 T3,哎这 \(70\) 都这么简单吗,哦不对这贡献计算挺复杂的,只会 \(h_p = 1\) 啊,死完了,后面想 T3,最后 1h 才看 T2,发现可以 KDT 乱搞,但是没时间写了,遗憾离场。
*T1
T2
给定三维空间内若干球,求出距离前 \(k\) 小的有序对的距离。
\(1 \le n \le 3\times 10^5,1 \le V \le 10^6\)。
这咋想到的。
首先二分答案,给每个球半径加上 \(\frac{mid}{2}\),问题转化为有多少对球相交。
考虑当前半径上限 \(R\),拉出来 \([\frac{R}{2},R]\) 之间的球,把空间按照 \(2R\) 划分为若干正方体,对于一块内,如果存在 \(O(\sqrt k)\) 个球,那么一定可以有 \(k\) 对相交。
这个结论豆包给出了一点证明,同一正方体内只会被划分为 \(8\) 个簇,然后之后再加球一定会相交,大概就是 \(O(\sqrt k)\) 级别,但是常数很大。
那么,\([\frac{R}{2},R]\) 我们每次暴力扫描邻域后加点即可,对于 \([1,\frac{R}{2})\) 之间的数,先判断其和 \([\frac{R}{2},R]\) 中球的交,然后递归下去做,每次重构一下就行了,一共只会做 \(\log V\) 轮,这里不太会分析啊,一轮的复杂度好像是 \(O(\sqrt{k\log V})\) 的?
总复杂度 \(O(n\sqrt{k\log V}\log V)\)。

浙公网安备 33010602011771号