CW暑假集训
集训模拟赛的题解应该都在 CWOI 杂题里。
主要就是题目的记录?不太想写游记。
简单题不会写。
7.7
考试,考得依托。
7.8
很趣味的数据结构!
感觉很有集训那味啊,就是前面讲一会简单的东西然后突然上强度。
gym100739E. Life as a Monster
还是挺简单。套路地把切比雪夫距离转成曼哈顿距离,然后做完了。
主要难点是卡空间。你可以用平衡树,\(\mathcal{O}(n)\) 的空间;或者你可以动态开点线段树,但是要注意在 int mid=(l+r)>>1 的时候 l+r 会爆 int(如果你有这个错误,大概会 mle on test 5)。
对了,\(T\) 记得及时膜 \(BASE\),不然 a1*T 会爆 long long(如果你有这个错误,大概会 wa on test 19)。
CF319E. Ping-Pong
考虑两个区间之间的到达关系。如果区间 \(a,b\) 有 \(b\) 包含 \(a\),则 \(a\) 对 \(b\) 有单向的可达关系;否则,若 \(a,b\) 有交,则两区间之间有双向的可达关系。在下文中,我们提到的“有交”指的是第二种情况,包含关系会单独说。
因为有交的区间有双向边,不妨把它们缩成一个内部任意两区间可以相互到达的联通块,以联通块内最左/最右的端点作为这个联通块的代表区间。在考虑两个区间是否能走到时,考虑他们所在的连通块的代表区间是否有包含关系是等价的。
为什么这是正确的?下面证充分性和必要性。
充分性:考虑两个代表区间中较小的那个。在这个小区间中任选一个区间 \([l,r]\),并在大区间中找到区间 \([L,R]\) 满足其是最靠后的满足 \(L\ge l\) 的区间。根据连通块的定义,\([L,R]\) 一定包含 \([l,r]\)。且由于区间长度单调递增,两区间不同,可以从 \([l,r]\) 走到 \([L,R]\);
必要性:若区间 \(x\) 能走到 \(y\),令 \(A,B\) 为 \(x,y\) 的连通块内区间的集合,则一定有 \(a\in A,b\in B\) 满足 \(b\) 包含 \(a\)。因为两个代表区间一定是不交或包含的关系,则此时应证明 \(a,b\) 的代表区间 \(a',b'\) 不会有 \(a'\) 包含 \(b'\)。若 \(a'\) 包含 \(b'\),考虑 \(A\) 中左端点在 \(b\) 中的最靠右的区间和右端点在 \(b\) 中的最靠左的区间,这两个区间需要与 \(b\) 相交,矛盾。
写起来需要特判一下两代表区间相同的情况。
CF487E. Tourists
因为题目要求不经过重复点,我们考虑点双。根据点双的定义,我们路径上经过的所有点双,它们里面的最小值是可以取到的,所以你考虑把它缩点。
但是点双是会重点的,不能直接缩。我们考虑一种叫圆方树的结构——对于所有点双,建一个对应的虚拟点,称为方点;把这个点双里的所有点全部向这个点连边,称为圆点。显然方点与方点间由圆点相连,这就构成了一棵树。
对这棵树树剖,定义圆点权值为题目中所给,方点权值为它对应点双内所有点权值最小值,原问题等价于求这棵树对应路径上经过的所有点的点权最小值。直接这么写在修改时不太好做,因为你需要修改包含它的所有方点。我们考虑略微修改一下方点点权的定义——修改为它所有儿子的点权最小值。这样每次修改点权时只用改它父亲这一个方点了。可以对每个方点开 multiset 来维护。
有一种特殊情况需要考虑:当 \(u,v\) 的 \(\text{lca}\) 为方点时,需要再考虑 \(fa_{\text{lca}(u,v)}\) 的点权。
CF1284D. New Year and Conference
假设 a 区间不交,b 区间相交,你可以开一棵线段树,维护 \(eb_j=i\) 的所有 \(j\) 中 \(sa_j\) 的最大值和 \(ea_j\) 的最小值。枚举一个区间,区间查即可。时间复杂度 \(\mathcal{O}(n\log n)\)。
当然,有一个更加牛逼的做法。维护集合 \(A\),里面的二元组 \((i,j)\) 表示 \([sa_i,ea_i]\) 和 \([sa_j,ea_j]\) 有交,\(B\) 同理。你只需要判断 \(A\) 和 \(B\) 是否相等即可,这个可以 hash。
更具体地,你对每个点随机一个权值 \(v_i\),集合 \(S\) 的 hash 值就是 \(\sum\limits_{(i,j)\in S}v_iv_j\)(这样定义是为了消除 \(i,j\) 间的顺序)。求 hash 值的时候可以从左到右枚举端点 \(i\),枚举过程中记一个变量 \(x\),表示左端点不大于 \(i\) 且 右端点不小于 \(i\) 的区间的权值和,可以这样计算。
有一些细节啊。比如左端点相同的区间记得算相互的贡献;还有要因为端点相交也算相交,维护时要先加后减。
时间复杂度也是 \(\mathcal{O}(n\log n)\),瓶颈是排序/离散化。
7.9
CF1149C. Tree Generator™
从直径的求法入手。一个最显然的想法是两次 dfs 求直径,可惜它行不通。
不妨转化一下思路:直径等价于树上最长的一条路径。对于一条路径 \((u,v)\),\(\text{dist}(u,v)=d_u+d_v-2d_{lca}\)。这跟括号序列有什么关系?对于两个点 \(u,v\),设它们在括号序列中对应点为 \(l,r\),那么 \(d_{lca}=\min\limits_{i=l}^r\{d_i\}\)。所以求直径等价于在括号序列里求三个点 \(x\le y\le z\) 使得 \(d_x+d_z-2d_y\) 最小。
显然三个数同时加减一个数对答案没有影响,所以我们可以只用考虑在这个区间内每个位置的深度(左右括号对应 +1/-1,深度就是前缀和),像维护最大子段和一样维护一下相关信息转移即可。
CF226E. Noble Knight's Path
CF264E. Roadside Trees
设一棵树初始高度为 \(h\),种植时间为 \(t\),当前时间为 \(T\),则它当前高度为 \(h+(T-t)\)。我们可以把所有树的高度都减 \(T\),转化为初始高度为 \(h-t\),不生长的树。
注意到加入一棵树的时候比它矮的树至多有 10 棵,删除一棵树的时候在它前面的树也至多有 10 棵。不妨开两颗线段树,分别以高度和位置为下标,记录从尾到头的最长下降子序列。每次操作至多进行 10 次修改,时间复杂度 \(\mathcal{O}(n\log n)\)。
P6292 区间本质不同子串个数
BOJ18755 Cyclic Distance
HDU7144 Treasure
手办
无原题。
给定 \(n\) 个二维平面上的点 \((x_i,y_i)\),问有多少对 \((i,j)\) 满足以下条件:
-
\(x_i<xj\),\(y_i<y_j\);
-
不存在 \(k\) 满足 \(x_i<x_k<x_j\),\(y_i<y_k<y_j\)。
保证不存在 \(x_i\) 相等或 \(y_i\) 相等。\(n\le 2\times 10^5\)。
7.10
7.11
7.12
7.13
7.14
7.15
7.16
7.19
还是 lk 讲杂题!
CF848C
CF1036G
CF955F
秒了!
考虑一个 \(\mathcal{O}(n^2)\) 的 dp:定义 \(f_{i,j}\) 表示在以 \(i\) 为根的子树里以 \(i\) 为根的最大 \(j\) 叉树的深度。发现对于 \(j\le 2\),\(f_{i,j}\) 的值都不超过 \(\log_{2}n\),我们可以交换一下答案和状态。定义 \(f_{i,j}\) 表示在以 \(i\) 为根的子树里以 \(i\) 为根的深度为 \(j\) 的树可能的最大叉。转移可以二分,最后把 \(j=1\) 的答案加上去,总复杂度 \(\mathcal{O}(n\log^2 n)\)。
CF811E. Vladik and Entertaining Flags
感觉挺简单的,\(n\le 10\) 基本等于明示做法了。
考虑线段树,为了支持合并维护一下当前区间最左和最右的联通状况,复杂度 \(\mathcal{O}(n\alpha(n)m\log m)\)。
想法很简单,写起来最开始稍微有点懵,推荐自己实现一下。
CF1680F
dxm 前几天讲过差不多的题(CF19E),鉴定为原。
这个所谓“宽松”的条件,其实就是问至多删一条边,能否得到一张二分图。因为二分图删一条边还是二分图,所以原问题就是删一条边能否得到二分图。这个就跟之前讲的那道一模一样了。
CF1699E
wc,我怎么贺做过。
考虑枚举这个 \(\text{min}\) 的值,最小化 \(\text{max}\)。定义 \(f_{i,j}\) 表示把 \(j\) 分解成 \(\ge i\) 的数能得到的最小的 \(\text{max}\)。显然答案就是 \(\max\limits_{i=1}^n\left\{f_{\text{min},a_i}\right\}-\text{min}\) 的最小值。
发现如果从大到小枚举 \(\text{min}=t\) 的话每次只会有 \(f_{t,kt}\) 的值会发生变化,时间复杂度 \(\mathcal{O}(n\ln n)\)。

浙公网安备 33010602011771号