2023 3 月二阶段总结
这两周大部分时间状态都很差,整个人和梦游一样想要睡觉,非常 sb。
不知道以前的学习状态是不是这样,于是可以理解为什么菜。
3.19 晚自习
晚上在整理回顾前两周的题目,整理到一半被 zqm 抓住问 Easy 这道题,是一个我没有注意到的细节问题!
发现 zqm 问的和我的做法不完全相同,于是讲了我的做法,并尝试解决 zqm 采用的做法的问题,一共可能花了 50min 左右。
然后去口胡 ABC,想了很久 EX 但是不会/ll,滚回来继续整理题目。
计划就是没有计划!
3.20 自习
- 补充完 OI Tricks
- 找 zz 的一道不在题目列表里面,疑似是 xx opencup grand prix of Moscow 的维护差分序列的典题
- CF377E Cookie Clicker:承3.13,总算是搞明白了这道题,加深了对于斜率优化的理解。长远来看,斜率更大的显然更优。但是这里显然应该表述为 kx + b 的形式,其中 b/k 是为了凑够 c[i] 的最小时间。设 fi 表示刚刚减去了 c[i](凑够了 c[i])之后,此时 剩余金钱-已花费时间 \times 当前斜率 的最大值,fi 实际上就是 kx + b 的 b 的意思,减去的时间乘斜率可以理解为对函数进行的平移。考虑当前要维护的是啥,维护的实际上是一个“上凹壳”,即按照斜率从小到大加入直线,把这些直线形成的图形的上轮廓刻画出来,由于斜率更小的短期可能更优,所以维护的是“上凹壳”,随着 c[i] 的增大,不断把一些短期也不优的直线弹出。
- CF1082F Speed Dial:思路简单的 DP,但是实现需要注意细节。
- ARC146E Simple Speed:经典,自从做过了 20230203 T3 ,从来没有怕过这种题。转移系数是比较精巧的,注意计算开头是一段下降/结尾是一段上升的情况,luogu 题解写得很好。DP 状态只有 O(n)
- [BalkanOI2011] timeismoney | 最小乘积生成树:令人惊艳的套路。
- [BZOJ5088]Wash:老典贪心。
- [BalticOI 2014 Day1] Sequence:枚举 N 的最低位 i,所有数字可以表达为 \(10x+i\dots 10x+9,10(x+1)\dots 10(x+1)+9\dots\),给每一个位置算出对应的最低位之后,可以判定出一个位置的限制是否已经被解决,发现对于剩下的是一个剩下的问题:找到最小的 x,使得 \(x,x+1,x+2,\dots\) 的十进制表示包含某一些数,递归做即可,复杂度 \(T(n) = 10T(n/10)+O(n) = O(nlogn)\)
今天状态是不如 HL 的,存在较长的摸鱼,需要调整!
不要留下遗憾,拜托了,另一个我。
3.21 自习
今天状态还行。
- 「Ynoi2015」 盼君勿忘:由于出现次数不同的只有 sqrt 种,所以可以莫队,然后用一个 unordered_map 维护所有出现过的 出现次数,每次询问扫描每一种出现次数计算答案。这样的问题是会被卡常,换成手写链表不会有更好的表现。一个优化是,对于出现次数 >sqrt 的,才采用上述的方式;对于出现次数 < sqrt 的,每次暴力从 1 扫到 sqrt 即可。
- [IOI 2014]Holiday:决策单调性+主席树区间前 k 大。
- CF896E Welcome home, Chtholly:对每一个块维护一个桶表示区间内数字的出现次数和max。考虑一次修改操作,假如 x * 2 <= max,那么考虑把 1...x “贴”到 x+1...mx 上;否则将 max-x...max 贴贴。可以发现的是,这样操作,可以保证我的 max - min 始终是在下降,并且由于值域和 n 同级,所以如果我可以 O(DS) 做到将两个数字贴贴,那么复杂度就是 O(DS n)。将两个数字贴贴显然可以用并查集做,对于散块,利用并查集还原当前值之后暴力重构即可,重构次数 O(N);对于询问,整块询问直接调用并查集即可,散块暴力枚举并利用并查集还原。
- CF1498F Christmas Game:树上阶梯博弈题。定根,那么可以看成 k 个子游戏,游戏 \(i\) 包含了 \(dep_u \bmod k = i\) 的所有结点,最后显然是这些游戏的 SG 值的异或和。考虑一个子游戏,考虑菊花的情况,发现此时等价于 Nim 游戏,考察两层的情况,发现第二层实际上是无用的,因为另一者可以模仿操作,将刚刚移动到第一层的棋子直接移动到根节点;进而发现偶数层无用,那么可以将移入偶数层 \(\Leftrightarrow\) 移动到根,所以可以把所有奇数层的看成是 Nim 游戏。换根 DP 即可。
- [USACO23FEB] Hungry Cow P:以为是 线段树分治+线段树上二分+线段树区间覆盖 无脑码农题,但是被打败了。问题出在:线段树二分的时候,问题是在 01 串中找到位置 l 后第 x 个 0,限制了位置 l,搞得我线段树二分到 mid 的时候不会计算左边的 siz 总和了。我的解决方案是考虑:需要考虑 l 的限制的 mid 只会出现在 l 到根的路径上,即我只需要提前把这 log 个 siz 算出来就好。更为优雅的解决方案是,考虑 l 后第 x 个 0,等价于 1 后第 x+(1...l-1 中 0 的个数)个,这个是可以容易计算的。另外犯了一个严重的错误,可持久化线段树不能 pushdown,警钟敲烂,不知道是第几次犯这个错误了。当然这个做法的代码实现复杂度比较高,更为优雅的算法是 楼房重建线段树/兔队线段树,线段树上每一个节点维护 out[rt] 表示 rt 右侧溢出的 1 的个数即可。
- CF1580B Mathematics Curriculum:显然考虑按值域从大到小构造,容易分析得到:放入最大值后,实际分成了两个子问题;形式化的,是笛卡尔树上的问题。然后就剩下简单 dp 了。
- ARC142E Pairing Wizards:算是自己分析出来的(毕竟听过一遍)。瞎 gb 画图分析可以发现仅仅剩下 bx > ax, ay > by 这种情况是难蚌的,此时要么是 ax->bx, 要么是 ay->by,或者两者一起上也行,只是不优。仿照 HNOI切糕,网络流建模即可。
3.22 自习
今天上午脑子不是很能转;下午晚上比较可以。
- 写了这么久的 fread,终于明白了原理(
- CF1223G Wooden Raft:考虑枚举 y,把值域分成 [ky, ky + y) 的段,这样一个非常好的性质就是值域段的个数总和 \(O(nlogn)\)(这警示着要注意考虑 log 出在调和级数的情况)。可以计算出如若不管 2\times x 的需求,可以拿到 \(\sum \lfloor\frac {a_i}y\rfloor\) 个 y。考虑这两个 x 如何出现,假如被某一个单挑了(令 2x = ai),那么这个单挑者必然是某一个值域块内的最大值;进一步的,实际上是 一个后缀的值域段的最大值,即将每一个值域段视作其 mod 下最大值,场上的后缀最大值,这是因为注意到选取了一个 ky 比较大的值域段单挑 x,损失的 y 的段数增加,可能不合法;一个不是后缀最大值的位置显然是不优秀的,因为可以注意到的是:一个后缀最大值不一定非要损失 k 个 y,可以保留一些 y 以换取合法性。假如是被最大次大打了,维护后缀最大次大类似做,此时 x = 次大值;特别小心是一段 mod 意义最大值+一段实际值比他大的值,此时 x = 最大值,段数会多损失一段。
- [CODE FESTIVAL 2016 Final H]Tokaido:nb 题,问题差不多是在问每次给定 DP 初值,算结果。在对于 DP 转移的不断观察简化之后,发现 DP 答案和初值的关系是简单的,观察到初值值域较小,于是直接预处理答案。具体的,首先可以设 \(f_{i, 0/1}\) 表示 i 是一段开头且会被 A/B 拿,此时是 B/A 在做决策。然后发现 f_{i,0} + f_{i, 1} 是相反数;然后发现 f_i 不重要,重要的是一个后缀最小值,具体的,可以把整个过程看作
int mn = sum[n - 1] - 初值
,然后for i = n - 2 ...3 mn = min(mn, 2 * sum[i] - mn)
;发现转移等价于说,对于当前的 (mn, i),找到最大的 j,使得 mn > sum[j],然后变成 (2sum[j]-mn, j),每一个值看成一个点,让 \(v\in (sum[i], sum[i + 1]]\) 连边 \(2\times sum[i] - v\),可以算出对于一个初值,经过这个 DP 得到的答案。 - CODE FESTIVAL 2017 Final E Combination Lock:3.20 心心念念的 zz 的维护差分序列的妙妙题。
- H 神的序列:集合 Hash 大放光芒!咋不长记性,每次都想不到集合 HASH。剩下的是一个前缀异或、前缀询问0的个数,分块即可。
- [USACO23FEB] Watching Cowflix P:思路在 2023 HL 集训里面写得很清楚了。剩下的问题实际上是通过 dp 值反推“树上背包”的合并方案,比较有趣。
- 「QOJ4827」Message Made of Noise:小学奥数题。新引入一个 # 表示重复上一位,AAAA 可以被表示成 A#A#
- CF1559D2 Mocha and Diana:优雅构造。考虑最终一定可以把初始连通块个数少的变成一棵树,否则边数不对,那么能连就连这个想法便被允许了,因为无论何时都可以找到可以链接的边,问题是怎么找。一个巧妙的思路是,先尝试尽量和 1 号点连边,设在 A 中与 1 相连,在 B 中不与 1 相连的块组成集合 S,反之,组成集合 T,容易发现这两个集合里面随便抽出一对均可。
- [Ynoi2008] stcm:分治 DFN 序大放光芒!!!非常震撼。或者 哈夫曼树+类整体二分。
- LOJ6197 法克:首先需要“猜”到答案 = 最小可相交链覆盖,然后结束,学习了不用传递闭包的最小可相交链覆盖。
3.23 模拟赛
- 7:50 T1 过大样例
- 8:00 T1 过拍,过边界 case
- 9:20 T2 自闭
- 10:20 感觉这把注意力很不集中/fn/fn
感觉这把没有做到全力以赴,没有做到集中。发现很 T2 奇怪,脑子就摆烂了,就开始胡思乱想、神游天外,这怎么做得出来!
后面去搞 T3,用力思考但是 GG。
T2:考场上一直思考的是寻找性质,简化问题。首先可以归纳分析出缩点之后,DAG 可以被提成一条链和一些飞边;注意到一个很好的性质是如果走的是一个环,那么是没有代价的,所以我的策略应该是走一些 1 代价的路径,使得剩下的局面可以通过只走环的方式处理掉。
一直猜结论猜结论猜结论,但是都是假的。
思考部分分,感觉要用最小路径覆盖的一块知识,这样看下来更不好做了。
知道最后每条边的经过次数形如 w + yk 的形式,但是非常懦弱,轻轻碰了一下 枚举 y/构造 y 这个方向就跑了,因为直觉看来这个分配是没法做的。
solution:
首先,应当考虑当前局面的答案如何计算,(由于可以一条边可以被一条路径经过多次)不应采用愚蠢的路径覆盖之类,发现是一个优美的计算式:\(\frac 12\sum |in_i-out_i|\),等价于对于每一条路径,在起点和终点各计算到一次。
稍微思考一下,形式化当前的问题:可以操作任意次,每次选择一对 \((u, v)\) 使得 u 可达 v,让 au-=k, av+=k,使得 \(\sum |a|\) 最小化。
显然有费用流算法,注意一个 \(a>0\) 做一次 -k 刚好 \(<0\) 的特殊情况,这种情况只会发生一次。然后自然考虑模拟费用流。
如果整个图是强连通,那么将 a 按照 \(>0\) 和 \(<0\) 分类之后随便做。
否则,多的限制是 u 可以到达 v,由于缩点之后可以看成链,所以 u 可以到达 v 当且仅当 u 所属的强连通分量的拓扑序更小。于是按照拓扑序逆序做即可。
此题关键点在于 列出答案的计算式并形式化题目。一定要勇敢,敢于尝试。
T3:对后缀排序的深入挖掘
首先随便有 \(O(n^2)\) hash 做法。
为了方便 SA,将整个串翻转,设 \(fi = 1/0\) 表示后缀 i...n 是否合法。
那么现在是需要对于每一个 i,判断所有的 \(j < i, f_j = 1\),是否有 \(s_{j...i - 1}=s_{i, 2i - j - 1}\)
黄神给出了一个巧妙的结论:只需要检查 \(i - j < \sqrt n\) 和 \(|rk_i - rk_j| < \sqrt n\) 的部分即可。
正确性:如果检查了所有 \(i - j < \sqrt n\) 的发现都不行,设最大可行的在 j,知道 i - j > sqrt。那么对于所有的可行的其他的 j^{\prime},至少前缀至少包含 {j...i - 1},这个前缀长度 > sqrt,那么 j^{\prime} 的个数就会 \(< sqrt\),显然这 sqrt 个应该在 rk 相近的里面找。
Dynamic Reachability:bitset 练习题。对询问分块,先默认不存在被询问的边。为了常数,把剩下的点先缩点,然后跑 Bitset传递闭包,但是只开 被询问到的点的个数 大小。设关键点个数 k,从而可以处理出 O(k^2) 条边,表示这两个关键点不用关键边是否可达。然后对于每一个询问,在已有的 bitset 的基础上,暴力加上修改的边,暴力跑 bfs 求出答案,bfs 再使用 bitset 优化。
3.24 自习
- CF1799H Tree Cutting:巧妙的 DP,设 \(f[u][s]\) 表示通过砍子树 u 内的边并保留 u 这一块,可以构造出集合 s 中 c[i],感觉这个 DP 状态是非常危险的 DP 状态,因为砍树边的顺序是很重要的,而状态中没能体现出这种顺序关系,此时我们考虑通过约束转移来满足条件。转移首先 \(f[u][s]\gets f[u][t]\times f[v][s \backslash t]\),表示先不考虑 (u, fath) 这条边不砍。然后考虑 (u, fa) 要砍,对于一个状态 f[u][s],可以算出此时 u 子树还剩下的真实 real_siz。如若当前决定保留 fath 这边,设 s 中最高位的 1 在 highbit,那么枚举 c[highbit+1...k],与 real_siz 比较,看是否有新的满足;只枚举 highbit+1...k 实际上是为了满足“切掉子树以后子树内不能有操作”的限制。如果决定保留 u 这边,设 highbit 是 s 中最高的 0,即 u 已经构造 highbit+1...k 这些序列,然后看 real_siz 是否可以构造 c[highbit] ;实际上是为了满足“切掉子树外面以后所有的操作必须都在子树内”的限制。
- CF1250K Projectors:经典“区间覆盖”类网络流,常见思考是建立一个数轴,数轴上相邻两点的流量表示最多有几次不被线覆盖。本题中,可以知道一个时刻至多剩下 min(B, A+B-sum) 个普通投影仪不去覆盖它。求解方案,考虑从汇点每次退流量 1 的流即可。
- 「NOI2008」志愿者招募:上一题的姊妹题。
- 餐巾计划问题:经典问题。
- 洛谷P8347 「Wdoi-6」另一侧的月:通过对于菊花图的分析,发现如果图上全是奇度数点,那么后手赢麻了;否则,先手一定可以找到一个偶度数点,使得操作这个点之后存在一种保留连通块的方式,使得那个连通块内全是奇度数点,那么先手赢麻。
- [USACO22DEC] Palindromes P:非常巧妙的计算答案的方式,看了很久答案计算。对于一个给定的区间,设 ai 是 1 的出现位置,容易贪心发现答案是 \(\sum |a_i + a_{m - i + 1} - (n + 1)|\),现在的问题是对于 n^2 个 l,r 计算这个式子。惊讶的发现 f_{l, r} 存在某种递推关系之类之类,然后通过巧妙的实现做到了 n^2 求解,具体看代码算了/hsh。
还在 UOJ 群对于一道博弈论题的讨论中搞明白了这样一个定理:
经典的“反转棋子问题”的每个格子可以视为一个子游戏,所以整个局面的 SG 函数值就是所有黑格子的 SG 函数值异或起来的值。
3.25-3.26 全真模拟赛
DAY1:
- 8:40 T1 初步猜想
- 9:00 T1 过拍,md,差点不会写双指针
- 10:20 T2 小自闭。
- 11:00 T2 自闭
- 12:30 T3 自闭
中午搜到了原题,然后一看 T1 炸了,手打了一遍交上去只有 10pts,知道 GG 了。
下午补午觉,然后看懂了 T23 的题解,感叹技不如人。
DAY2:
- 9:30 T1 \(n<=7\)
- 10:00 还是不会用 T1 随机的性质
- 10:20 T1 不甘心
- 11:30 放弃 T1
- 12:00 T2 部分分
下午回家摸鱼+睡觉。
感觉做 D2 的体验感远高于做 D1 的体验感,感觉 D2 全是可做题,D1 都不太可做。
实际上是 D1 的 T23 非常准确的考到了 wyb 知识点的薄弱处。
打了两把尽力局,但是结果却不如人意。
心态变化:D1T1 激动地猜结论->专注用力分析 D1T2->发现连最简情况都不会做,无奈放弃->专注用力分析 D1T3->发现推出来的东西不会算,失望->发现 D1T1 挂了,非常失望伤心难过->重整旗鼓->用力分析 D2T1->卡在 \(8^n\log V\) 动不了了,简单一瞥 D2T2/3->狂暴形式化 D2T1,做不了,失望放弃,期待考后的正解->感觉 T2 像原,观察出了一些显然的结论但是时间不够没太管,暴力走人->用力分析 T3,觉得 T3 很可做啊,时间不够遗憾离场。
错误:
- D1T1 GG,虽然对拍了很多组,但是造的数据强度太低了;那么问题出在分析不严谨,当天考场太急了,太想给后面多留点时间,太想快速做完 T1,太想证明自己,分析太草率了。
- D1T23:最开始学的时候就没有太弄懂 欧拉回路 和 Floyd 的原理,尤其是 Floyd,一直处于一个半懂不懂,感觉很对但是又没有把握的状态。
- D2T1 前前后后花了将近 2h30min 的时间,但是只有第一个小时拿了分,时间分配很有问题,暴力硬刚不可取。
- D2T2 //freopen 喜报,这好像是从学 OI 以来的第一次,无 fuck 说。
方案:
- 请把分析写在草稿上;戒骄戒躁,勿慕名利。名利是双刃剑,是动力与方向,也是毒药。
- 速速查漏补缺。分析的时候,应时刻思考那些信息是我需要的,当发现维护了一个很复杂的信息,但是只调用了一小部分作为贡献的时候,就要小心了。
- 不要刚 T1,题目难度可能倒序!
优点:
- D1 考完充分重整旗鼓,D2 考完充分重整旗鼓。
wyb 的难度排序:D1T2 > D2T1 > D1T3 > D2T2 > D2T3 > D1T1,大概把,没有仔细排。
自从 春测信心模拟赛 一来,wyb 感到一种希望;春测失利让人感到一点不确定;在 HL 的表现有令人感到欣喜;最近几场的不尽人意,却又是让人惶惶然了。
一直在 希望和失望 之间焦灼着,似乎是我太贪心了,想要的太多。
我希求终结这样一个因为失望伤怀而停步不前的过程而一直前进,但是没有失望便无论希望,没有驻足便无谓前行。我一直都在前进。
现在想想又感觉挺有希望的,很多题目都是一步之遥,甚至可以说是非常接近,只要再往前勇敢一步,但是也许这一步就是天堑。
upd 3.27:一步之遥:
- D1T1:只枚举了最大值作为 mod
- D1T3:没想到 floyd,想到了不用 floyd 直接维护连通性,但是 tarjan 上脑非要用 vector 维护出每一个 scc 里面到底有啥,实际上只需要维护每一个点是否可达即可。
- D2T2:想到了可以看成一些长段,想到了横竖段之间 \(\delta \le 1\),但是没有深入。
- D2T3:已经列出了 不考虑不可达点 的 dp 方程,只需要再乘上一个简单系数就是正解。(虽然说不会 Mod 任意的自然数幂和就是)
3.27 自习
- 给 zqm 讲 D2T3,对这道题有了更加清楚的认知。
- 讲了两遍(初三+zqm) graph problem with small n^2 和 koxia with sequence,有了更加清楚的认知
- 「联合省选 2020 B」丁香之路:这种问题,一定考虑欧拉回路啊
- [省选联考 2021 A/B 卷] 图函数:不断拆分贡献,细化贡献的艺术。细化到计算对于所有 i, j 使得有 \(i \to j, j\to i\) 不经过 \(< i\) 的路径的最晚时刻,这个可以枚举 i,倒序加边,维护正反图可达性。对这个上 bitset 优化可以得到优秀的复杂度。
- CF843E Maximum Flow:聪慧的网络流。第一个想法是做上下界网络流,直接限制不能流的边的容量上限 0,但是问题是可能导致满流的边太多了,因为所有没有容量的边其实都是满流的。那么先寻找一个最小割使得满流的边尽量少且这个割集不包含题目要求的不能走的边,假如我有了这个割集,那么就可以在刚刚的上下界可行流上,令不属于割集的容量搞成 inf,割集边容量=流量即可。注意到这个割集需要保证不能包含一些边,进行如下建模:对于不能走的边 (u, v),连边 (u, v, inf);必须走的边,连边 (u, v, 1), (v, u, inf);实际上是直接考虑残量网络上的情况。
- AGC044D Guess the Password:首先可以 \(\sum\) 次问出每一种字符出现次数,顺便得到总长度。发现我支持问一个 t 是不是答案的一个子序列。考虑假如只有两种字符,分别有 a, b 个,那么实际上有 a + b - 1 次问出答案的方法,即考虑把 b 个按次往 a 中塞,塞完问一问是不是一个子序列就知道塞这个位置对不对。n 更大的时候,归并即可,总复杂度乘一个 log 之类;也可以按照字符个数排序,类似启发式合并一样做。
- CF1336D Vasily the Bear and Beautiful Strings:找规律,找完规律之后剩下简单组合数。
3.28 讨论赛
感觉今天比较困,需要调整。
讨论赛给 T1 胡了一个做法,找出了 T2 缩点之后可以搞成外向树的性质感觉剩下的东西随便做,T3 是原,然后看题解。
发现 T1 胡的做法没有人写,但是有一个类似的魔改轻重链剖分的 dfn 顺序的做法差不多。我的做法是直接维护每一条边的颜色,将每一条边放在儿子上,对于一次修改,区间覆盖一些重边,在做区间覆盖的同时打上 tag,表明这些点的轻边都应该是白色,单点修改 log 个轻边是黑色,同时需要清理推掉在 father 链上的标记。
询问的时候,重链直接问,对于一条轻边,问一问标记即可。这样麻烦的地方在于 lca 处需要一点讨论,但是问题不大。
更巧妙的做法是,每次直接给路径上的每一个点染成一个没有出现过的颜色,那么一条边是黑边当且仅当这条边两端点颜色相同,这个可以线段树维护区间左右端点颜色维护区间答案。
T2:搞成外向树之后,剩下的是一个求可达性的问题,建立虚树之后暴力 bfs 即可。
T3:巨大 splay 题,没有想法。T4 好像比较神仙,没有看题解,直接跑路了。
下午晚上随便乱看,看了一点 线性规划 筛法 LGV Border理论 全局平衡二叉树。
3.29 讨论赛
咕咕咕咕呱,无颜面对江东父老!
3.30
上午看了看今天的题,发现相对比较容易。T1 看起来就很憨憨,T2 是比较高明的构造,T3 是比较憨憨的 DP,T4 是比较憨憨的 DS
然后看了看一些 OI tricks。
下午晚上随便看了一点题。