经过一阶段校内集训,然后简单过完唯一一天暑假(也是我生日)之后,第二天(\(\text{Jul }20\text{th}\))也是被拉去广大附中继续集训坐牢两个星期了。
\(\text{Jul }20\text{th}\)
早上 \(8\) 点到达柳州站,第一件事先去打报销凭证……牛魔的这票的质量怎么这么差?早知道不打了!
车次是柳广原神 \(\text{D}3753\),车型是宁局原神 \(\text{CRH2A}\),本务谁跟谁重联忘了,后面补上,一进车厢就又能闻到那熟悉的镜酱的脚臭味了……在车上尝逝打音游但一会之后就放弃了。路途不远,\(3\) 个半小时就到广州了,下车之后就坐滴滴来了广大附中。
这学校嘛,布局看着挺不错的,也很生态,就是各种地方都在施工,总给人一种半成品的感觉?我去什么条件啊,宿舍楼装电梯?还有球场? 不愧是牢广,微距了。总之到了宿舍之后一整个下午都尝逝睡觉回蓝,但新环境拼尽全力无法睡着,就这样迷迷糊糊去上晚自习了。其实晚自习上还一直在打之前学的莫队www
\(\text{Jul }21\text{st}\)
\(0721!\)(喜)
牛魔的,昨天晚上一点没睡好,困死我了。第一天讲构造,一个早上也是拼尽全力无法不打瞌睡,只能说 \(12\) 道题大概也就听懂一半多点吧,不过也确实有一些能总结的地方。
\(1.\) 对于有
UDLR
(上下左右)操作的题目,可以考虑将移动旋转 \(45°\) 后放大为 \(\sqrt 2\) 倍,这样就能转化成 \((1,1),(1,-1),(-1,-1),(-1,1)\) 这样两个方向上都有移动的操作,就能够独立两个维度来考虑了。对于一个维度,只有 \(-1\) 或 \(+1\) 两种操作。然后我们考虑在坐标中加上时间戳(即每次移动都额外向正方向再移动一步),这样就变成了 \(0\) 或 \(+2\) 两种操作。最后,再缩小成原来的 \(\dfrac{1}{2}\) 倍,就成功转化为了 \(0\) 或 \(+1\) 两种操作。CF538G Berserk Robot\(2.\) 对于给定图的构造,因为图的性质较少,而树的性质较多,可以考虑提出 \(\text{dfs}\) 树或者其他的什么树来分析。P7320 「PMOI-4」可怜的团主 用到了树的两个性质:
- 覆盖一棵树需要 $\ge \left \lceil \dfrac{叶子数}{2} \right \rceil $ 条路径,当且仅当所有路径的端点为叶子时取等(当路径数为奇数时,至多一条路径可以只有一端为叶子)。
- 一棵树的所有叶子可以构成一个独立集(互相没有边连接)。
\(3.\) 对于树的刻画,“无环”优于“连通”。CF611H New Year and Forgotten Tree
\(4.\) 给出 \(n\) 个点的完全图,可以考虑归纳第 \(i\) 到 \(n\) 个点与前 \(i-1\) 个点的关系。ARC131E Christmas Wreath
\(5.\) 两个完美匹配取并,得到若干偶环。CF741C Arpa’s overnight party and Mehrdad’s silent entering
牢广这块物价真的是贵的离谱,广大附中食堂自选快餐 \(2.28\) 元\(/ 50\text{g}\),我已经收着力打了,却还是直接给我干到 \(27.45\) 元了,这都够我在树高吃两三顿了……最离谱的是我看这个学校里面的人打的饭菜也跟我差不多量,合着广爷搁学校里都顿顿 \(30\) 块,那出了学校不得贵死啊?
下午和晚上拼尽全力只能改出 \(3\) 题……
欸?意外收获?我的机位居然有一个野生的三月七 \(\text{badge}\),是 \(\text{QuAn}\) 酱画的那个头像。也不管是哪位学长的遗产,不过现在是我在这个机位,只希望她接下来两个星期能安慰一下我的心灵吧。
\(\text{Jul }22\text{nd}\)
这回倒是睡好了,但是今天讲数据结构,果不其然中途又打瞌睡了……总共 \(17\) 道题,\(4\) 题线段树 \(+\) \(3\) 题笛卡尔树 \(+\) \(2\) 题字典树 \(+\) \(8\) 道杂题(甚至其中 \(7\) 道都是黑!)笛卡尔树我之前是一点都没接触过的说……听懂一半算我输。还是先来个总结吧:
\(1.\) 序列 \([l,r]\) 排序后可以构成公差为 \(k\) 的等差数列,当且仅当:
- 该序列的极差等于 \(k(r-l)\),这通过线段树维护区间最值实现查询。
- 该序列的差分序列最大公因数为 \(k\),这通过线段树维护差分序列的区间最大公因数实现查询。
- 当 \(k\neq 0\) 时,该序列的数互不相同,这通过
unordered_map<int, set<int>>
维护每个数上一次出现的位置实现判断,其中set
是某个值出现位置的集合。P5278 算术天才⑨与等差数列
\(2.\) 一棵包含 \(k\) 个点的无标号有根树可以使用一个长度为 \(2(k - 1)\) 的括号序列表示。它们本质上等价于欧拉序(进入和退出节点时时间戳都增加)中通过一条边搜索以及回溯的过程,左括号对应深度 \(+1\),右括号对应深度 \(-1\)。根据括号序列计算深度前缀和序列 \(\{d_n\}\),那么 \(d_i\) 对应就是欧拉序中第 \((i+1)\) 个点的深度(第一个点是根),序列中区间 \([l,r]\) 的最小值就代表欧拉序中第 \((l+1)\) 和第 \((r+1)\) 个点的 \(\text{LCA}\) 深度。所以树上两点 \(u,v\) 的距离 \(\text{dis}(u,v) = \text{dep}_u + \text{dep}_v - 2\text{dep}_{\text{LCA}(u,v)}=d_{l-1}+d_{r-1}-2\min\limits_{i=l-1}^{r-1}d_i\),其中 \(l,r\) 分别为 \(u,v\) 的欧拉序。CF1149C Tree Generator?
\(3.\) 笛卡尔树:一种简化的 \(\text{Treap}\)。对于序列中的某个节点,其在这个序列的笛卡尔树上的键值(节点编号)等于下标,优先级等于它的数值。笛卡尔树分大根形态和小根形态,对于序列 \(\{a_n\}\) ,区间 \([l,r]\) 中的最小值等于小根笛卡尔树上 \(\text{LCA}(l,r)\) 的优先级(数值),最大值等于大根笛卡尔树上 \(\text{LCA}(l,r)\) 的优先级(数值)。笛卡尔树的建树是 \(O(n)\) 的。P5854 笛卡尔树的建树模板
笛卡尔树的应用场景:区间最值(一般用线段树,因为笛卡尔树并不平衡),序列中某个数左/右侧第一个大于/小于它的数等。
这回倒好,就只改出了第一题,交上去的 \(\text{AC}\) 代码还被 \(\text{Hack}\) 掉了……
晚上又讲了一些线段树理论,发现其实树高那会讲的其实还有些纰漏,于是就把树高那部分删去了,这里再重新总结一下。
\(1.\) 半群线段树(不需要懒标记)
可以维护一个序列 \(\{a_n\}\),其中 \(a_i \in D\),\((D,*)\) 是一个半群。它可以实现:
- 单点修改:给定 \(i,x(1\le i \le n,x \in D)\),\(a_i \leftarrow x\)。
- 区间查询:给定 \(l,r(1\le l \le r \le n)\),求 \(*_{i=l}^r a_i\)。
半群要求 \(*\) 运算满足结合律。
常见问题:带单点修改的区间求和/求积/求矩阵积/求最大子段和。
\(2.\) 环线段树(需要懒标记)
可以维护一个序列 \(\{a_n\}\),其中 \(a_i \in D\),\((D,*,\otimes)\) 是一个环。它可以实现:
- 区间修改:给定 \(l,r,x(1\le l \le r\le n,x \in D)\),对于所有 \(i(l\le i \le r)\),\(a_i \leftarrow x * a_i\)。
- 区间查询:区间查询:给定 \(l,r(1\le l \le r \le n)\),求 $ \bigotimes\limits_{i=l}^r a_i$。
环要求 \(*\) 运算满足结合律,\(\otimes\) 运算满足结合律和交换律,且 \(*\) 运算对 \(\otimes\) 运算满足分配律。
相比于半群线段树,环线段树的一个节点 \(i\) 上,除了要维护 \(S_i \in D\) 外,还需要维护一个 \(T_i \in D\),即所谓的懒标记,其意味着节点 的子树仍然有一些修改尚未下传,这些修改等效于左乘 。通常而言,我们约定 \(S_i\) 表示的是不考虑 \(i\) 的祖先上的懒标记的修改时,
区间内的 \(a_i\) 之和 \((\otimes)\)。修改或查询时,当要递归到 \(i\) 的左右儿子时,更新左右儿子 \(S,T\) 的值,然后将 \(T_i\) 重置为幺元。\(3.\) 标记永久化
在一些特殊的场景中(比如树套树),可能受时间或空间限制,也可能受某些规则的约束,我们无法下传标记,此时需要进行标记永久化,也就是标记不下传。为了做到这点,我们必须保证 \((D,*)\) 不仅仅是一个半群,而且是一个群,即需要有乘法 \((*)\) 单位元和逆元。
假设我们需要给区间 \(i\) 整体左乘 \((*)\) 一个值 \(x\),它的祖先上有 \(T_a,T_b\) 两个懒标记,由于 \(S_i\) 表示的是不考虑 \(i\) 的祖先上的懒标记的修改时的区间和,其真实值 \(S'_i=T_a*T_b*S_i\),修改后就是 \(S''_i=x*T_a*T_b*S_i=T_a*T_b*(T^{-1}_a*T^{-1}_b*x*T_a*T_b)*S_i\),所以只需令 \(x'=T^{-1}_a*T^{-1}_b*x*T_a*T_b\),即可 \(S_i \leftarrow x'*S_i,T_i \leftarrow x'*T_i\)。
看着好像是在《你搁这搁这呢?》实际上只是对于区间加来说,乘上逆元直接抵消掉了。但实际上,有些时候乘上逆元并不能直接抵消。
\(4.\) 值与标记的分离
其实很多时候,所谓“环线段树”并不能很好地描述我们要做的事情,而是得把维护的值 \(S\) 和懒标记 \(T\) 认为是不同的“东西”。也就是说,我们有值集合 \(V\) 和标记集合 \(A\),并且有运算:
- \(V \leftarrow V * A\) ——给值“加上标记”的结果
- \(A \leftarrow A * A\) ——标记的复合(满足结合律)
- \(V \leftarrow V \otimes V\) ——值的“求和”
一个经典例子:\(V\) 为 \(n\) 维向量集合,\(A\) 为 \(n\times n\) 的矩阵集合。其实 \(n\) 维向量完全可以也看成 \(n\times n\) 的矩阵,从而在数学上将值与标记统一,分离仅仅是为了思维的方便。
如果问题的操作都是线性变换,那么可以直接维护 \(n\) 维向量,将 \(n\times n\) 的转置矩阵作为懒标记。矩阵与其乘法、加法是构成环的,所以可以用环线段树维护。
常见问题:
- 区间加/区间乘/区间求和:维护二维向量 \(\left[ \begin{array}{c} a_i \\ 1 \end{array} \right]\) 的和,每次区间 \(+x\) 相当于乘上一个 \(2\times 2\) 的矩阵 \(\left[ \begin{array}{cc} 1 & x \\ 0 & 1 \end{array} \right]\),区间 \(\times x\) 相当于乘上 \(\left[ \begin{array}{cc} x & 0 \\ 0 & 1 \end{array} \right]\)。
- 区间加/区间历史版本和:维护三维向量 \(\left[ \begin{array}{c} a_i \\ h_i \\ 1 \end{array} \right]\) 的和,区间 \(+x\) 相当于乘上 \(\left[ \begin{array}{ccc} 1 & 0 & x \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{array} \right]\),累加一次版本 \((h_i \leftarrow h_i + a_i)\) 相当于乘上 \(\left[ \begin{array}{ccc} 1 & 0 & 0 \\ 1 & 1 & 0 \\ 0 & 0 & 1 \end{array} \right]\)。
但是,这些经典问题大多用不上线性代数的做法。因为可以观察到,我们所维护的向量,以及转置矩阵含有大量的 \(0\) 和 \(1\),这得以让我们把它们优化成单变量懒标记。同时,矩阵变换的时间常数极大,效率会略逊于单变量懒标记。但线性代数的做法可能更好想(只要能看出所有操作都能通过线性变换实现),正确性和时间复杂度是得以保证的,对于非经典问题,尤其是在考场上,如果想到了线代做法,就应该立刻打上。尽管最后可能因为极大的常数而丢掉一两个点,但这总比干瞪眼瞪不出单变量懒标记的优化而爆零好太多了。
\(\text{Jul }23\text{rd}\)
今天上午是 \(\text{NOIP}\) 模拟赛。
\(\text{T}1\) 本来只打了个 \(40\) 分的暴力,后面发现是很简单的 \(\text{DP}\),期望得分 \(100\text{pts}\),实际得分:\(20\text{pts}\) ——啊??怎么爆了??还不如打暴力呢 死因:做法假了,不是 \(\text{DP}\),实际上还真只需要暴力就可以了,我之前的暴力不对www。
修改后得分:\(100\text{pts}\)。
\(\text{T}2\) 不会写,输出个无解看看能得多少,期望得分 \(1\text{pts}\),实际得分:\(0\text{pts}\) ——沟槽的捆绑测试
修改后得分:\(100\text{pts}\)。
\(\text{T}3\) 暴搜乱搞,期望得分 \(20\text{pts}\),实际得分:\(20\text{pts}\)。
\(\text{T}4\) 暴力乱搞,期望得分 \(15\text{pts}\),实际得分:\(15\text{pts}\)。
期望得分(总):\(136\text{pts}\),实际得分:\(55\text{pts}\),\(\text{Rank}:69/72\)。
修改后得分:\(235\text{pts}\)。
只能说考的一坨,\(\text{Rank}\) 垫底,\(\text{T}1\) 和 \(\text{T2}\) 本该拿到更高的分数,甚至应该全切,但没有做到。不过 \(\text{T3}\) 和 \(\text{T4}\) 倒是预期完成了,骗到 \(35\) 分已经可以算是收获达标了,在考场上就应该这样。如果 \(\text{T}1\) 和 \(\text{T2}\) 稳定发挥,那么这个分也算是能完成省一的夙愿了。
\(\text{Jul }24\text{th}\)
今天讲 \(\text{DP}\),全都听不懂! 直接开摆,写基础的橙黄 \(\text{DP}\) 题去了。数据结构讲蓝紫黑题就算了,给我讲 \(\text{DP}\) 蓝紫黑题我是真的会死的。
下午勉强把 AGC061C First Come First Serve 大概弄懂了,但仅此而已。
有点新东西:
\(1.\) 二项式反演:
\[f(n)=\sum_{i=0}^n \binom n i g(i) \Rightarrow g(n)=\sum_{i=0}^n(-1)^{n-i} \binom n i f(i) \]囿于篇幅不作证明。
常见于 \(f(n)\) 表示“至多 \(k\) 个元素满足条件”的计数,\(g(n)\) 表示“恰好 \(k\) 个元素满足条件”的计数。大多数情况下,\(f(n)\) 是较为好求的,而想直接计数求解 \(g(n)\) 比较困难,此时可以考虑用反演来求得。
经典问题:P1595 错位全排列,即求 \(n\) 个元素全不放在原位 \((\forall i \in [1,n], a_i \neq i)\) 的排列数。
设 \(g(n)\) 表示恰好有 \(n\) 个错位的排列数,\(f(n)\) 表示至多有 \(n\) 个错位的排列数,也就是不带任何限制的排列数,所以 \(f(n)=n!\)。根据二项式反演,有
\[g(n)=\sum_{i=0}^n(-1)^{n-i} \dbinom n i i!=\sum_{i=0}^n \frac{(-1)^i n!}{i!} \]这便是经典的错位全排列公式。通过预处理出 \(1\) 到 \(n\) 的阶乘,这个式子的结果就可以 \(O(n)\) 算出,这对于链接里 \(1 \le n \le 20\) 的数据范围完全是大炮轰蚊子。如果作为二项式反演的板子,应该带上大数取模和线性递推乘法逆元开到 \(1\le n \le 10^8\) 量级。
二项式反演还有另一种形式:
\[f(k)=\sum_{i=k}^n \binom i k g(i) \Rightarrow g(k)=\sum_{i=k}^n(-1)^{i-k} \binom i k f(i) \]常见于 \(f(k)\) 表示“至少 \(k\) 个元素满足条件”的计数,\(g(k)\) 表示“恰好 \(k\) 个元素满足条件”的计数。
P4859 已经没有什么好害怕的了 先 \(\text{DP}\) 出“至少”的情况,然后用反演求出“恰好”的情况。
\(2.\) \(K\)-\(\text{D}\) 树:是一棵可以存储 \(K\) 维空间中的点信息,支持插入、删除和高维空间中对数级时间复杂度搜索的平衡二叉树,树上每个节点对应 \(K\) 维空间中的一个点。当 \(K=2\) 时,能够实现将二维平面转换成二叉树,快速查询平面最近点对 (P1429)。建 \(K\)-\(\text{D}\) 树通常用维度轮换法或最大方差法,囿于篇幅不作展开。
今天真的是倒霉完了,其实一开始说好每天 \(2\) 小时放风玩玻璃砖的,\(\text{Jul 20th}\) 晚上又说只有周末才能玩,给我闷了三天。好不容易今天晚上 \(20\) 分钟放风,本想着把 \(\text{Codeforces}\) 账号弄好,结果网站刚好被 \(\text{Bad Gateway}\) 在外面进不去,真的是麻了。
\(\text{Jul 25th}\)
宿舍楼一大早上起来就放大石碎胸口,鉴证英雄这一块。
今天讲 \(\text{DP}\) 优化,继续开摆,写黄绿 \(\text{DP}\) 题。
下午有点受不了了,奖励了自己两三道线段树问题的板子。
什么?体锻时间比 \(400 \text{m}\)?第一名送机械键盘?\(\text{byd}\) 那么热的天谁爱跑谁跑去吧,反正我直接一个弃权。什么?推迟啦?好似喵~
晚上 \(\text{Codeforces}\) 能进了,还好之前放风的时候登上了 \(\text{QQ}\) 这下就有邮箱了,但现在虽然注册好了,洛谷这边反倒还绑不上(绷)。
\(\text{Jul 26th}\)
宿舍楼一大早上起来又放了一遍大石碎胸口,真的是吉列的豆蒸。
今天上午是第二场模拟赛。
\(\text{T1}\):暴力乱搞,期望得分:\(10\) ~ \(35 \text{pts}\),实际得分:\(\text{0pts}\)。怎么一分没骗到?? 死因:题意根本没懂。实际上,这就是个黄题。
修改后得分:\(\text{100pts}\)。
\(\text{T2}\):暴力 \(\text{DP}\),期望得分:\(\text{30pts}\),实际得分:\(\text{30pts}\)。
\(\text{T3}\):暴力乱搞,期望得分:\(\text{25pts}\),实际得分:\(\text{25pts}\)。
\(\text{T4}\):摆了。期望得分:\(\text{0pts}\),实际得分:\(\text{0pts}\)。
期望得分:\(\text{}\) \(\text{65}\) ~ \(\text{90pts}\),实际得分:\(\text{55pts}\),\(\text{Rank}:36/42\)。
修改后得分:\(\text{155pts}\)。
考的和上一场一样差(甚至分数都一模一样),除了第一题外其他题目一共骗到了 \(\text{55pts}\),和上一场问题一样,有难度的题目能骗到分,但简单题切不掉,考虑日后方向转向黄绿基础题,并且多打一点基础赛。
要是再这么下去我真的想 \(\text{AFO}\) 了,闹麻了都,花这么多精力有个几把用啊?还不如好好搞 \(\text{whk}\)……
下午讲博弈论。暑假真的是各种不方便,下午因为停电还得换机房……两个机房的人凑在一个机房里面,空调还不给力,热死了。这下子变成群魔乱舞了,一排过去同时坐了:图寻大蛇(平均 \(5\) 秒一道题,正确率高达 \(90\%\)),魔方大蛇(粗略估计有 \(\text{sub15}\) 的水平),文言文大蛇(拿文言文资料出来看结果被教练抓包),洛谷领域大蛇(主页及其花里胡哨),异史氏曰:梅逸阁诗人。
\(\Huge广州蚊子真的好多啊!\)
我怀疑我的花露水被掉包成了蚊子信息素一类的东西。
考虑到今天模拟赛的总结,晚上 \(8\) 点打一场 \(\text{ABC416}\),看看自己什么货色。
评价为:小学生都不如。\(\text{ABC}\) 级别的比赛,场上只写出来 \(\text{A}\) 和 \(\text{C}\),\(\text{Rank}\ge7000\),太丢人了,可以期待今年炸成什么样了。
\(\text{Jul 27th}\)
宿舍楼一大早上起来又放了一遍大石碎胸口,三回啊三回。
今天是休息日,改一下昨天 \(\text{ABC416}\) 的题目。