飘花效果

暑假作业做题与模拟赛游记(没写完)

蒟蒻挑战每一个专题最多只有一个作业不 AK……(不 AK 也要补起来 QwQ)

好我咕咕了中间一大堆没写就算了:(直接跳模拟赛了。

\(2025.7.28 \sim 2025.7.29\) 字符串专题

\(Day 1\)

开幕雷击,一上来就是冷门的字符串。

今天是 trie、KMP、manacher、exKMP。

\(T1\) [USACO07DEC] Best Cow Line G

本来想申请降绿但是不能工单调整相邻难度,后来有个学长帮忙降绿了但是被管理警告了。。。

考虑弱化版,每次显然能够选择较小的字母就选较小的那一端,难点是如果两端字母相同该怎么取。

其实也很好想,如果两端都相同,除了回文,必然存在一个长度 \(pos \le \lceil \frac{(tail - head + 1) }{2}\rceil\) 满足 \(s_{[head \dots head + pos - 1]} \neq s_{[tail - pos + 1\dots pos]}\),此时两端延伸出去的 \(pos\) 个位置的字符分别为 \(ch1\)\(ch2\),若 \(ch1<ch2\) 则优先选择左端,否则优先选择右端。

然后一直重复做这三种情况,容易证明一定能够得到最优解。

弱化版直接暴力求 \(\mathcal O(n^2)\),但是这题不能暴力,于是我们采用老套的哈希 + 二分来查找这个位置,时间复杂度为 \(\mathcal O(n\log n)\)

\(T2\) [SCOI2003] 字符串折叠

考虑到 \(n = |s|\) 较小为 \(100\),于是考虑区间 DP。

\(f_{i ,j}\)\(s_{[i \dots j]}\) 经过折叠的最短长度,一种转移是枚举一个中间点 \(k\)\(i\le k < j\)),将左边和右边分别经过折叠的最短长度相加,转移如下:

\[f_{i ,j} = \min\limits_{k = i}^{j - 1} \{f_{i ,k} + f_{k + 1,j}\} \]

接下来我们唯一的方法是将整个区间折叠,因此枚举循环节长度 \(l\),满足 \(l \mid (j - i + 1)\)\(l\neq j - i + 1\)(不能全部折叠,即使可以也肯定更劣),如果条件成功我们要判断 \(s_{[i\dots j]}\) 是否能够以长度 \(l\) 分为相同的 \(\frac{j - i + 1}{l}\) 部分,如果可以那么进行如下转移:

\[f_{i ,j} = \min\limits_{l = 1}^{j - i} \{f_{i ,i + l - 1} + digit (l)\ + 2\} \]

其中 \(2\) 指的是包裹的括号((...)),\(digit(x)\)\(x\) 十进制位下的位数,可以预处理。

字符串一次比较是 \(\mathcal O(l)\) 的,比较 \(\frac{n}{l}\) 次,因此一次 \(\operatorname{check}\) 的时间复杂度为 \(\mathcal O(n)\)

总时间复杂度是 \(\mathcal O(n^3\max d(n))\)\(1\le n\le 100\)\(d(i)\)\(i\) 的因数个数),并且跑不满,可以通过。

然后我们考虑用哈希优化,如果一个字符串 \(s\)\(l\mid |s|\),记 \(len = |s|\)),那么如果 \(s_{1 \dots len - l} = s_{l + 1 ,len}\),那么这个串一定可以用以 \(l\) 为长度的子串构成循环节。

证明很显然,可以自己画画,大概以 \(l\) 为一段,可以一直由前一段推出后一段。

可以用哈希优化,时间复杂度为 \(\mathcal O(n^3)\)(此时瓶颈变为枚举断点 \(k\) 了)。

\(T3\) [国家集训队] 最长双回文串

先跑一边 manacher,然后考虑怎么做。

我们对于一个非分隔符的最大能够扩展的回文长度 \(d_i\)(不包括 \(i\)),当两个端点 \(i\)\(j\)\(1\le i < j\le |s|\)),如果存在 \(i + d_i \le j - d_j\),那么两个区间有交集,可以构成双回文串,只要两个中的其中一个字符串缩短一点大小就可以了。

考虑这东西很像二维偏序,我们把它丢进权值线段树中,然后 query 一下就行了,时间复杂度为 \(\mathcal O(n\log n)\)

题解区还有 \(\mathcal O(n)\) 做法,但是个人感觉这种做法比较好想(老师也用了这种做法(bushi))。

\(T4\) [USACO2.3] 最长前缀 Longest Prefix

很套路的 DP,DP 也很好想。

\(f_i\) 表示能否用单词表匹配到 \(s\) 的第 \(i\) 位,初始状态 \(f_0 = 0\)(所以需要将字符串下标从 \(1\) 开始记),然后暴力枚举 \(\text{card(P)}\) 中的字符串 \(P\),如果满足 \(s_{i - |P| + 1 \dots i} = P\)f_i |= f_{i - |P|},注意只要满足一个 \(1\) 就可以匹配到,所以是 |=

时间复杂度为 \(\mathcal O(|S|\text{card}(P)|P|)\),可以卡过,考虑优化。

我们发现时间复杂度里面多了一个 \(\mathcal O(|P|)\),于是考虑用哈希优化掉这个,时间复杂度为 \(\mathcal O(|S|\text{card}(P))\),不卡时间复杂度。

\(T5\) Password

全军覆没因为是 CF

注意到前中后都要相等,我们可以先考虑前后两个条件,答案 \(|T|\) 就是 \(s\) 的最长 border。

然后考虑中间,如果 \(T\) 在位置 \(i\) 结束,那么 \(T\) 一定是 \(s_{[1\dots i]}\) 的一个 border。

因为 \(i\neq 1 ,|s|\),因此理论答案的最大值是 \(mx\gets \max\limits_{i = 2}^{|s| - 1} nxt_i\)\(nxt\) 的定义和 KMP 中一致。

然后我们从 \(|s|\) 开始跳 border,设跳到的 border 长度为 \(l\),则如果 \(l > mx\) 则不符合我们的需求,需要 \(l\le mx\),我们找到的第一个满足条件的 \(l\) 即为 \(|T|\),输出 \(s_{[1\dots l]}\)

特别地,如果 \(l = 0\) 输出 Just a legend

时间复杂度为 \(\mathcal O(n)\)

\(T6\)\(T7\)\(T8\)\(T9\):对应模板 manacher、KMP、字典树、扩展 KMP/exKMP(Z 函数)。

因为是模板,因此此处省略:(

完成情况:AK。

\(Day 2\)

今天是子序列自动机、AC 自动机和后缀数组。

\(T1\) 公共子序列

为了方便,我们设三个字符串分别为 \(S1\)\(S2\)\(S3\),字符串下标从 \(1\) 开始。

先建出子序列自动机,然后设 \(f_{i ,j ,k}\)\(S1_{[i\dots n]}\)\(S2_{[j\dots n]}\)\(S3_{[k\dots n]}\) 这三个子串中的不同公共子序列个数。

同子序列自动机,我们设 \(nxt_{0/1/2 ,i,j}\) 为第 \(1/2/3\) 个字符串中,在 \(s_{0/1/2,[i+1\dots n]}\) 中下一个字符 \(j\) 出现下标的值加一(即右边一个字符。),如果没有则 \(nxt_{0/1/2,i,j} = 0\)(这边把字符的 ASCII 码减去 \(97\) 来压缩空间)。

转移的话我们枚举下一个公共字符 \(ch\),需要满足 \(S1\)\(S2\)\(S3\) 接下来的位置都存在至少一个字符 \(ch\),我们贪心选择最接近的字符(所以要用子序列自动机),则一定可以通过 DP 来求解问题。

特别的,我们在建子序列自动机的时候,会存在 \(nxt_{0/1/2 ,n ,s_n} = n + 1\),这样答案会多统计一个,所以我们最后在答案处要减一

转移式如下(我们记 \(nxt_{0 ,i ,ch}\)\(nxt0\)\(nxt_{1 ,j ,ch}\)\(nxt1\)\(nxt_{2 ,k ,ch}\)\(nxt2\)):

\[f_{i ,j ,k} = 1 + \sum\limits_{ch = 0}^{25} [nxt0 \neq 0][nxt1\neq 0][nxt2\neq 0]\times f_{nxt0 ,nxt1 ,nxt2} \]

其中包含 \(+1\),是因为自己本身也算一个字符串。

然后用记忆化实现即可,时间复杂度为 \(\mathcal O(n^3)\),答案即为 \(f_{1 ,1 ,1} - 1\)

\(T2 ,T3 ,T4\):分别对应子序列自动机、AC 自动机和后缀数组模板。

此处省略。

\(T5\) [JSOI2007] 字符加密

我们要对所有读法进行字典序从小到大排序,这和我们后缀排序中对后缀进行排序有点相像,于是想到后缀数组(最小表示法肯定没人会去想就只能这个了)。

因为是环问题,所以我们破环成链,然后考虑用后缀数组求解。

我们写出所有后缀,手玩容易发现所有读法都在这些后缀中作为前缀出现过了。

所以尽管后面出现了那么多字符,但是排序结果还是由前缀(读法)决定。

而对于相同的前缀,怎么排都没关系,反正最后一个字符都是一样的,输出结果无影响。

所以直接上后缀排序即可,注意一下最后输出 \(\forall sa_i \le n ,s_{sa_i + n - 1}\),这个直接说有点难懂,倒是手玩比较好理解。

时间复杂度为 \(\mathcal O(n)\)

\(T6\) [AHOI2005] 病毒检测

奇怪的题,一眼感觉可以 DP,但是后来觉得不行(还是我太菜了),而老师做法是 DP。

我稍微偷懒就算了:(

题解里有 trie 做法,还有一道半加强半弱化版本可以用 AC 自动机来做:https://www.luogu.com.cn/problem/P3167

有空再补。

\(T7\) [POI 2005] SZA-Template

不理解为啥要加进来,但是加深了我对 KMP 的理解:(

容易发现答案是整个字符串的 border、border 的 border……(以此类推)中满足条件的最短的字符串。

于是我们设 \(f_i\) 为文章第 \(i\) 位置所需的印章最小值,初始值 \(f_i = i\)(即整个字符串为一个印章)。

另一种就是 \(f_i = f_{nxt_i}\),表示继承 border 的答案,但是继承这个答案需要有一些条件。

如果 \(f_{nxt_i}\) 能够覆盖 \(s_{[1\dots nxt_i]}\),那么一定能覆盖 \(s_{[i - nxt_i + 1 ,i]}\)(border 的定义)。

也就是说,如果 \(f_{nxt_i}\)(不要搞错)能够覆盖到的最远距离 \(\ge i - nxt_i\),则一定能覆盖 \(s_{[1 ,i]}\)

证明:

如果覆盖的最远距离 \(> i - nxt_i\)

对于两个相交串 \(A\)\(B\),如果它们都能被一个字符串 \(k\) 表示,那么它们的交集也一定能被 \(k\) 表示出。此时 \(k\)\(A\)\(B\) 的交集(我们可以手玩助于理解)。

如果能覆盖的最远距离为 \(i - nxt_i\)

只要覆盖了 \(s_{[i - nxt_i + 1,i]}\) 即可,上面提到过。

因此我们用一个辅助数组 \(rgt_i\) 表示用所有以前长度为 \(i\) 的印章能够到达的最远边界,直接 DP 即可。

\(T8\) [USACO06DEC] Milk Patterns G

容易发现答案满足单调性:

  • 如果不存在\(x\) 的子串,使得出现次数至少为 \(k\),那么也不可能出现长 \(x + m\)\(1\le m\le +infty\)\(x + m \le n\))的子串出现次数至少为 \(k\) 次(很好理解)。

  • 如果存在长 \(x\) 的子串,使得出现次数至少为 \(k\),那么一定存在长 \(x - m\)\(1\le m\le +infty\)\(x - m\ge 1\)),比如说这个出现至少 \(k\) 次子串的前缀。

因此用二分即可,每次暴力比较字符串,用 map 维护,但是我们还能优化。

我们发现取一个字符串好像不太优美,于是我们用哈希替代,可做到 \(\mathcal O(n\log^2 n)\)\(Hash\) 值可能很大要用 map / unordered_map)。

然而我们也可以用后缀数组。

我们想到 SA 中的一条性质:相邻的 \(sa_i\)\(sa_{i - 1}\) 代表的后缀的前缀相似度越大。

我们又发现,任何一个子串 \(t\)\(s\) 的出现次数,是 \(t\)\(s\) 的所有后缀中,作为前缀的出现次数,

也就是说,这个子串一定是后缀排序后,连续的一段子串的前缀。

于是我们使用 \(height\) 数组,因为我们发现 LCP 是可以使得答案最大化,那么就是求所有 \(height\) 中连续长 \(k - 1\)\(height\) 的最小值,这些长 \(k - 1\) 的最小值的最大值。

说起来可能有点拗口,改成数学表述就是:

\[ans = \max_{i + k - 2\le n} \{\min height_{[i \dots i + k - 2]}\} \]

然后时间复杂度就是 \(\mathcal O(n)\) 了。

\(T9\) 不同子串个数

这边直接套结论,网上各种学习笔记基本都把方法写在里面了,换句话就是模板。

答案是 \(\frac{n(n+1)}{2} - \sum\limits_{i = 2}^n height_i\)

完成情况:

AK。

\(2025.7.30\sim 2025.8.1\) DP 专题

\(Day 3\)

今天是线性、区间、树上、状压、数位 DP、简单背包大杂烩。

\(T1\) [USACO18DEC] Teamwork G

水题,完全没有绿的难度。

\(f_i\) 为前 \(i\) 头奶牛分组的最大技能水平和,转移如下:

\[f_i = \max\limits_{j = \max\{0 ,i - k\}}^{i - 1} f_j + (i - j)\times \max\limits_{j1 = j + 1}^i a_{j1} \]

直接转移即可,这一块区间最大值可以用 ST 表维护,也可以倒着转移不用 ST 表。

\(T2\) [DTCPC 2024] 小方的疑惑 10

好题,我不会,竟然是背包思想的 DP。

如果有 \(x\) 对括号并列,比如 \(\texttt{()()()()}\)\(x = 4\),那么有多少个合法的括号序列?

容易发现答案为 \(4 + 3 + 2 + 1 = 10\),推广到 \(x\in \mathbb{N^*}\),合法的括号序列个数即为 \(\frac{x(x+1)}{2}\)

再考虑如果有括号嵌套,先来一种简单的:\(\texttt{(()()()())}\),此时里面有 \(x = 4\) 个括号并列,外层有 \(1\) 个括号包裹,容易发现答案数量为 \(10 + 1 = 11\),这个 \(1\) 是整个括号序列,稍微手玩一下就会发现不存在任何前缀或者后缀(除了整个括号序列)使得组成的括号序列合法(左括号与右括号个数不等),这些真前缀和真后缀都是比 \(\texttt{()()()()}\) 多出来的括号序列,所以可以直接证明。容易推广合法括号序列个数为 \(\frac{x(x+1)}{2} + 1\),其中 \(1\) 也可以写作 \(\frac{1\times 2}{2}\)

然后还有 \(\texttt{(()()()())()()()}\),容易发现是上面这种情况的推广,但是我们换一种角度,这是由 \(x = 4\) 个“大”括号组成,其中一个“大”括号里面有 \(y = 4\) 个小括号并列,同样可以计算多出来的合法括号序列个数,还是同上,可以发现总个数为 \(20\)(具体省略),容易推广个数为 \(\frac{x(x+1)}{2} + \frac{y(y+1)}{2}\)

最后我们将上述的情况混合,比如 \(\color{red}{(}\color{blue}{()()()()}\color{red}{)(}\color{green}{()()()}\color{red}{)}\color{purple}{()()()}\),可以发现合法的括号序列个数为红、蓝、绿、紫三种颜色的括号并列,它们的答案(就是 \(\frac{x(x+1)}{2}\))之和。

这样就很明确了,我们设 \(a_i\)\(i\) 个括号并列时的合法括号序列个数(即 \(\frac{i(i+1)}{2}\))。接着我们设 \(f_i\)恰好存在 \(i\) 个合法的括号序列的最短序列长度,初始化 \(f_0 = 0\)\(f_i = +\infty\)\(1\le i\le 10^5\))。则转移如下:

\[f_i = \min\limits_{a_j\le i} f_{i - a_j} + 2\times j \]

我们发现这是一个背包模型,因此我们可以用背包的转移方式。

设我们需要预处理 \(a\) 的长度为 \(x\),因为 \(\frac{x(x+1)}{2}\le 10^5\)(不然肯定没有意义),因此得到 \(x\) 的范围为 \(2\times \sqrt{10^5}\) 左右,这样转移是 \(\mathcal O(V\sqrt{V})\),其中 \(V = 10^5\),不会超时。

然后对于询问 \((n ,k)\),如果 \(f_k > n\) 则一定无解。

否则考虑怎么输出一个合法的括号序列,我们用 \(lst_i\) 表示有 \(i\) 个合法的括号序列,最少需要几对并列的括号。

在输出方案数的时候,我们用递归的形式输出,我们可以在第一个括号里面摆上剩下的括号,然后第 \(2\sim lst_k\) 个括号里面不加东西,因为答案是和的形式嘛。

最后如果发现有多余长度没有摆上任何括号,剩下的我们直接输出 ( 即可,这样构不成任何合法的括号序列。

分析到这应该明白为啥要最少了,这里留给读者自己思考。

\(T3\) [POI 2013] BAJ-Bytecomputer

容易发现改成除了 \(0\)\(1\)\(-1\) 除外的数一定不优,因此设 \(f_{i ,0/1/2}\) 为将 \(a_i\) 改成 \(-1/0/1\),让序列转化为非递减序列的最小代价,转移即可,答案为 \(\min\{f_{n ,0} ,f_{n ,1} ,f_{n ,2}\}\)

\(T4\) [AHOI2009] 同类分布

数位 DP 很显然。

然后直接做好像很困难。

但是我们发现各数位之和很少,最大为 \(9\times 17 = 152\)

因此我们可以暴力枚举各数位之和 \(mod\),然后我们需要:

  • 判断该数模 \(mod\) 是否为 \(0\)
  • 判断该数的各数位之和是否为 \(s\)

我们需要一个好的状态,设 \(f_{pos ,x ,sum}\) 为在第 \(pos\) 位,该数模 \(mod\)\(x\),各数位之和为 \(sum\) 的数的个数,然后可以直接转移了(\(mod\) 通过大力枚举)。

时间复杂度是 \(\mathcal O(\text{能过})\)

\(T6\) [SDOI2008] Sue 的小球

做过关路灯的这题应该很简单,设 \(f_{i ,j ,0/1}\) 表示拿到 \([i ,j]\) 中的小球,位置在区间左边/右边的最大分数,直接 \(\mathcal O(n^2)\) 转移即可。

注意所有小球的 \(x\) 坐标需要排序,这样才能确定转移正确性。

还有为了方便,我们可以把 Sue 的初始位置 \((x0 ,0)\) 也加进小球的下标中,那么初始化 \(f_{\text{排序后的 Sue 位置的下标},\text{排序后的 Sue 位置的下标},0/1} = 0\),其余都为 \(-\infty\) 即可。

\(T7\) [CERC2014] Outer space invaders

这个 \(1\le n\le 300\) 一眼区间 DP(虽然是错的分析出区间 DP,但是区间 DP 还是对的)。

一开始设 \(f_{i ,j}\) 为消灭外星人 \([i ,j]\) 的最低成本,但是发现不好转移。

于是我们把思路转到时间,设 \(f_{i ,j}\) 为消灭出现和死亡时间 \([i ,j]\) 的外星人,我们可以枚举消灭外星人的时间断点 \(k\),那么:

\[f_{i ,j} = \min\limits_{k = i + 1}^{j - 1} f_{i ,k - 1} + f_{k + 1 ,j} + \text{消灭花费} \]

容易发现干脆一次性消灭出现时间和死亡时间都在 \([i ,j]\) 的外星人的小号电池最优,假设存在不这样最优的,不管你怎么执行到头来还是要消灭最远距离的外星人,消耗的电量与一次性消灭的电量相等,所以答案一定不优。

因此 \(\text{消灭花费}\) 为在这个时间段的外星人离主播的最远距离。

但是时间范围最大为 \(10000\)\(\mathcal O(T^3)\) 可吃不消。

但是我们发现不同的时间最多有 \(300\times 2 = 600\) 种,并且把时间离散化并不影响答案,因此我们直接离散化然后暴力即可,时间复杂度为 \(\mathcal O(n^3)\)\(8\) 倍常数。

\(T8\) 没有上司的舞会

简单题,也是很多树形 DP 入门题。

\(f_{u ,0/1}\) 为选/不选节点 \(u\) 的最大快乐指数,用儿子转移即可,答案为 \(\max \{f_{1 ,0} ,f_{1 ,1}\}\)

\(T9\) 二叉苹果树

树上背包入门题。

\(f_{u ,k}\) 为在子树 \(u\) 保留 \(k\) 个树枝能够保留的最多苹果数量,答案即为 \(f_{1 ,k}\)

然而转移有点困难。

我们可以考虑按照子树顺序转移,比如 1-2 , 1-3,我们可以先算子树 \(2\) 的答案,再算子树 \(2,3\) 的答案,这样是为了方便下面转移。

对于转移,首先我们要枚举保留枝条数 \(i\)\(1\le i\le \min \{edges_u ,Q\}\)),其中 \(edges_u\) 为子树 \(u\) 含有的枝条个数。

然后对于 \(v\in \operatorname{son}(u)\),我们枚举该子树保留枝条个数 \(j\)\(1\le j\le \min\{edges_v ,i - 1\}\)),然后进行转移。

然后转移如下:

\[f_{u ,i} = \max \{f_{v ,j} + f_{u ,i - j - 1} + w\} \]

其中 \(w\) 是这条树边的边权,\(f_{u ,i - j - 1}\) 是不算这个子树,只保留前面子树的枝条个数(\(i - j - 1\))能够获得的最大苹果数。

值得注意的是,\(i - j - 1\) 需要没有进行过转移,所以 \(i\) 倒着枚举。

然后 \(v\) 无所谓了。

乍看这是 \(\mathcal O(n^3)\),但是有严格证明这是 \(\mathcal O(n^2)\)

\(T9\) [POI 2008] STA-Station

换根 DP 模板题,首先第一遍 DFS 考虑儿子对父亲的贡献,然后第二遍 DFS 让父亲求儿子的答案。

这种题目随机应变,往往第二遍 DFS 细节有点多。

然后没了,这边不作详细分析(包括下面这题)。

\(T10\) Accumulation Degree

还是换根 DP。

第一遍 DFS 很简单。

第二遍 DFS 需要分情况讨论边 \((u ,v)\)

  • \(u\) 为根。

  • \(v\) 为叶子。

  • \(\texttt{otherwise}\)

然后由父亲计算儿子的答案即可。

这里不作分析,我懒:(。

\(T11\) SAC#1 - 萌数

怎么会有这么萌的数,但是很烦的题目呢?

首先需要高精度计算 \(l - 1\) 的值(良心出题人)。

然后进行数位 DP。

首先注意到至少长度为 \(2\),我们可以让 \(l - 1\) 变为 \(\max\{10 ,l - 1\}\),如果 \(l > r\) 则无萌数。

然后我们试着打表,我们发现,如果一个数存在长度至少为 \(2\) 的回文子串,那么它一定含有至少一个长度为 \(2\)\(3\) 的回文子串。

这个很好证明。

然后我们设 \(f_{i ,p1 ,p2 ,0/1}\) 为第 \(i\) 位,上一位为 \(p1\),上上位为 \(p2\) 的不符合/符合要求的数,数位 DP 即可。记录 \(0\) 是因为方便记忆化。

\(T12\) [SCOI2005] 互不侵犯

状压 DP 模板题,设 \(f_{i ,state ,j}\) 为第 \(i\) 行,状态为 \(state\),之前(包括第 \(i\) 行)摆放了 \(j\) 个国王的方案数,答案为 \(\sum\limits_{i = 0}^{limit} f_{n ,i ,k}\)

这里转移不作讲解,因为这是状压 DP 模板。

\(T13\) [POI 2004] PRZ

枚举子集的状压 DP 模板。

\(f_i\) 为状态 \(i\) 包含的所有人过桥的最小时间,我们可以枚举一个子集 \(T\) 为这一轮过桥的人,那么转移即为:

\[f_i = \min\limits_{T \in i} f_{i \oplus T} + tim \times flag \]

\(tim\)\(T\) 状态包含的这些人的过桥时间最大值,\(flag\) 表示这些人的重量和是否大于桥承受重量,是则 \(0\),否则为 \(1\)

但是这样做时间有点卡,我们预处理状态的合法性和过桥时间,即可做到时间复杂度 \(\mathcal O(2^nn + 3^n)\)

完成情况

AK。

\(Day 4\)

今天是计数 DP、期望 DP、简单的 DP 优化(单调栈和单调队列)

\(T1\) [JSOI2007] 文本生成器

对于多模式串问题,我们不妨先建 AC 自动机,然后在 AC 自动机上 DP。

一般 AC 自动机上 DP 的套路都是一个维度为 \(f_i\) 为在 AC 自动机上的节点 \(i\) 的答案。

然后正着做比较难,我们考虑到总情况很容易算,是 \(26^m\),然后我们正难则反,计算不合法的数量。

我们设 \(f_{i ,u}\) 为前 \(i\) 个文章长度中,在 AC 自动机的节点 \(u\) 上的不合法字符串数量。

我们枚举文章长度 \(i\),节点编号 \(j\) 以及字符集 \(k\)\(0\le k\le 25\))那么转移如下:

\[f_{i ,trie_{j ,k}} = f_{i ,trie_{j ,k}} + f_{i - 1 ,j} \]

初始化 \(f_{0 ,0} = 1\)

最后不合法数量为 \(tot = \sum\limits_{i \in \text{AC 自动机的节点编号集合}} f_{m ,i}\),答案即为 \(26^m - tot\)

\(T2\) [NOIP2015 提高组]子串

我们设 \(f_{i ,j ,k}\) 表示在 \(A_{[1\dots i]}\) 中选出 \(k\) 个互不相交的子串,且按照它们在 \(A_{[1\dots i]}\) 中出现的顺序首尾相连后与 \(B_{[1\dots j]}\) 相同的方案数。

首先当 \(A_i = B_j\) 的时候才能转移。

一种我们可以不选子串,那么方案数为 \(f_{i - 1 ,j ,k}\)

另一种我们可以选子串,我们要在 \(A\) 中选长 \(L\) 的字符串,要求与 \(B\) 对应的一段相同,那么我们就要满足 \(A_{[i - L ,i]} = B_{[j - L ,j]}\)\(1\le L \le \min \{i - 1 ,j - 1\}\)),贡献为 \(f_{i - L ,j - L ,k - 1}\)

那么转移方程即为:

\[f_{i ,j ,k} = [A_i = B_j] \times \left(f_{i - 1 ,j ,k} + \sum\limits_{L = 1}^{\min\{i - 1 ,j - 1\}} [A_{[i - L ,i]} = B_{[j - L ,j]}] \times f_{i - L ,j - L ,k - 1}\right) \]

这样时间复杂度为 \(\mathcal O(nmk\min\{n ,m\})\),空间复杂度为 \(\mathcal O(nmk)\),都不能接受。

然后我们考虑消除 \(i\) 这一维,于是我们需要用一个辅助数组 \(sum_{j ,k} = \sum\limits_{L = 1}^{\min \{i - 1 ,j - 1\}}[A_{[i - L ,i]} = B_{[j - L ,j]}] \times f_{i - L ,j - L ,k - 1}\)

我们可以动态更新 \(sum_{j ,k}\),具体地,如果 \(a_i = b_j\) 则更新 \(sum\),否则清零。

更新 \(sum\) 的转移式(当 \(A_i = B_j\) 时):\(sum_{j ,k} = sum_{j - 1 ,k} + f_{j - 1 ,k - 1}\),其中 \(sum_{j - 1 ,k}\) 对应 \(\sum\limits_{L = 1}^{\min \{i - 1 - 1 ,j - 1 - 1\}}[A_{[i - 1 - L ,i]} = B_{[j - 1 - L ,j]}] \times f_{i - 1 - L ,j - 1 - L ,k - 1}\)\(f_{j - 1 ,k - 1}\) 对应 \(f_{i - 1 ,j - 1 ,k - 1}\)

然后 \(f_{j ,k} = f_{j ,k} + sum_{j ,k}\)\(f_{j - 1 ,k}\) 对应 \(f_{i - 1 ,j ,k}\)\(sum_{j ,k}\) 对应后面的和式。

初始化为 \(f_{0 ,0} = 1\)

此时时间复杂度为 \(\mathcal O(nmk)\),空间复杂度为 \(\mathcal O(mk)\),可以通过。

这题应该可以称为计数 DP。

T3 [TJOI2011] 01矩阵

水题,我都会做。

考虑到 \(n\)\(m\) 的最小值最多为 \(15\),如果 \(n < m\) 直接转置矩阵然后跑状即可。

但是逆天的是我竟然重复的状压写了两遍。。。

T4 [SCOI2008] 奖励关

注意到 \(1\le n\le 15\),所以考虑状压。

但是这题是期望 DP,一般期望都是从后往前 DP。

\(f_{i ,S}\) 为第 \(i\) 轮时,获得宝物的状态为 \(S\) 的分值期望。

\(key_i\) 为获得第 \(i\) 个宝物的前置宝物状态,转移我们枚举当轮获得宝物 \(j\),则有如下转移:

\[f_{i ,S} = f_{i ,S} \gets f_{i ,S} + \begin{cases} \max\{f_{i + 1 ,S} ,f_{i + 1 ,S | (2^{j - 1})}\} & key_j \in S \\ f_{i + 1 ,S} & key_j \notin S \end{cases} \]

很好理解,答案即为 \(f_{1 ,0}\),即初始状态啥宝物也没有。

\(T5\) [NOIP 2016 提高组] 换教室

额这题我转移不写了,太长了。

\(f_{i ,j ,0 /1}\) 表前 \(i\) 个时间段,\(j\) 次更换教室,这次是否更换教室的期望。

然后大力转移即可。

为了方便转移我们要预处理两个教室之间的最短距离,这题用 floyd 即可。

\(T6\) [HNOI2013] 游走

图上随机游走模板,用 AI 大力理解终于理解了。

我们可以先计算边的概率,然后分配权值再算最小期望。

我们可以把边的概率转化为点的概率,记 \(pri_i\) 为经过点 \(i\) 的概率,\(deg_i\) 为节点 \(i\) 的出度,那么对于一条边 \((u ,v)\),经过的概率为:

\[P((u ,v)) = \frac{pri_u}{deg_u} + \frac{pri_v}{deg_v} \]

很好理解,经过点 \(u\) 的概率,又要正好经过这条边,概率乘上 \(\frac{1}{deg_u}\),另一个节点同理,然后用加法原理加起来即可。

然后对于节点的概率怎么算呢?对于与点 \(u\) 相连的节点 \(v\),概率可以这么算:

\[pri_u = \sum \frac{pri_v}{deg_v} \]

然后就没了,但是细节,我们从 \(1\) 开始,自然经过这个点 \(i\) 的概率需要加一。

但是这是无向图,我们发现概率都是互相影响的,因为节点 \(n\) 是终点,我们不算贡献,那么这就是 \(n - 1\) 个点互相影响的概率。

我们可以把 \(pri_u = \sum \frac{pri_v}{deg_v}\) 的式子转化为方程组,这样有 \(n - 1\) 个方程组,我们就可以高斯消元了。

注意 \(1\) 的等式右边是 \(1\),其余是 \(0\)

然后接完就可以求出边经过的概率,然后贪心地分配权值就可以算出最小期望了。

\(T6\) 『STA - R3』Aulvwc

首先可以暴力推式子算出这个平均值。

附上我的草稿:

\[\frac{1}{B1} \sum\limits_{ i = 1}^{B1} a_{S_{1 ,i}} = \frac{1}{B2} \sum\limits_{ i = 1}^{B2} a_{S_{2 ,i}} = \frac{1}{B3} \sum\limits_{ i = 1}^{B3} a_{S_{3 ,i}} = \cdots = \frac{1}{Bk} \sum\limits_{ i = 1}^{Bk} a_{S_{k ,i}}= y \]

\(k\) 未知。

满足:

\[B1 + B2 + B3 + \cdots + B_k = n \]

\[\sum\limits_{ i = 1}^{B1} a_{S_{1 ,i}} + \sum\limits_{ i = 1}^{B2} a_{S_{2 ,i}} + \sum\limits_{ i = 1}^{B3} a_{S_{3 ,i}} + \cdots \frac{1}{Bk} \sum\limits_{ i = 1}^{Bk} a_{S_{k ,i}} = \sum\limits_{i = 1}^n a_i \]

\[B1y + B2y + B3y + \cdots + Bky = \sum\limits_{i = 1}^n a_i \]

\[y = \frac{\sum\limits_{i = 1}^n a_i}{\sum\limits_{i=1}^k B_i = n} \]

然后这就是个裸的背包问题,bitset 维护减少时间复杂度,注意一下细节即可 AC。

\(T8\) [CSP-S2019] 划分

好题,差点想到 \(\mathcal O(n^2)\) 做法,因为当时凌晨补题实在太困了。。。感觉也能冲一冲正解。

这我就不记录了,我懒,虽然是好题但是我懒,可以看题解。

\(T9\) [USACO11OPEN] Mowing the Lawn G](https://www.luogu.com.cn/problem/P2627)

水题,一维状态即可,暴力转移就行,但是会超时。

但是这是一个求区间 max 的形式,我们可以单调队列,但是这里我选择了线段树 A 了。

\(T10\) 蓬莱「凯风快晴 −富士火山−」

思路和疑问发这里了,求大佬解答,做法也在里面了不讲了。

\(Day 5\)(待补)

虽然我自学过斜率优化但是没学过 wqs 二分完啦,一眼就知道今天 AK 不了,先咕了。

\(2025.8.2 & 2025.8.4\) 数据结构专题

\(Day 6\)

第一天这么多模板,都学过,万岁!

\(T1 ,T2 ,T3 ,T4\) 对应模板 ST 表,哈希表,树状数组 \(1 / 2\),不讲。

\(T5\) 方差

简单,把方差拆出来,就发现需要维护区间平方和以及区间和,然后考虑区间增加 \(k\) 会对区间平方和产生啥影响,这题就做完了。

其实就是套路,这题也很著名?不仔细讲解。

\(T6\) 对应模板离线二维数点,不讲,感觉还不如跑 CDQ 好

\(T7\) 上帝造题的七分钟

珍爱生命,远离推式子。

二维 BIT。

同区间求和区间加的 BIT,我们只要推式子就行。

前方警告,这题要维护四个 BIT,最好还是写结构体省码量。

式子过程不记录。

\(T8 ,T9 ,T10 ,T11\),对应模板左偏树 \(2\),左偏树/可并堆,线段树 \(1 /2\),顺便安利一波自己线段树的模板题解

\(T12\) 城池攻占

实话如果今天不写左偏树我还看不出来这是左偏树。

对每个节点建立一个堆,堆内元素为初始攻击这个城池的士兵的初始战斗力。

考虑到从一个深度最深的节点,往上如果有死掉的士兵,那么当前战斗力一定是单调的。

因此考虑对这些堆进行删除与合并,这正是左偏树可以做到的事。

但是这题有乘法标记和加法标记,不要打错。

简单证一下就可以证明时间复杂度的正确性。

\(T13\) [NOI2002] 银河英雄传说 对应模板:带权并查集(可以算吧),不讲。

\(Day 7\)

也是虚空调试啊好吧,重构一次代码,虚空调试 \(N\) 分钟。

本来还以为有 xyz 最喜欢的平衡树(听 xxs 讲的),结果没有,本来还想嘲讽 xyz 的。

\(T1,T2,T3,T4,T5\) 对应模板:李超线段树,线段树合并,线段树分治,可持久化线段树 \(1/2\),不写。

\(T6\) 楼房重建

明显可以先处理斜率,然后问题转化为单点修改斜率,全局查询多少个斜率是其前缀的最大值。

我们记录 \(sum_i\) 为线段树上节点 \(i\) 的答案,每次修改后答案即为 \(sum_1\)

然后单点修改我们可以找到那个点修改斜率,然后我们需要一个恰当的 pushup

等等,这个 pushup 好像不一般,有点难。

然后不会做了,点开 TJ:(

我们记录 \(mx\) 为区间 max,分情况讨论:

然后我们记录 \(u\) 的左儿子为 \(ls(u)\),右儿子为 \(rs(u)\)\(mx\)\(mx(u)\),答案为 \(sum(u)\)

那么:

  • \(mx(ls(u)) \ge mx(rs(u))\),那么右儿子区间的贡献为 \(0\),答案为 \(sum(ls(u))\)

否则右边区间有贡献,继续讨论:

  • \(mx(ls(u)) \ge mx(ls(rs(u)))\),那么左区间贡献为 \(0\),直接查询 \(rs(rs(u))\)

  • 否则,我们查询 \(ls(rs(u))\) 的贡献,然后增加右区间的贡献,右区间的贡献即为 \(sum(rs(u)) - sum(ls(rs(u)))\),可以直接算(注意不是 \(sum(rs(rs(u)))\),这个只是对节点 \(rs(rs(u))\) 区间的贡献)累加即可。

然后我们进行递归,这题就做完了。

\(T7\) 对应模板:线段树分裂,不写。

\(T8\) CPU 监控

吉老师线段树的前置模板题,可以参照 oi-wiki 写。

新颖的是有区间覆盖为 \(v\),我们可以维护一个标记,也可以区间与 \(v\) 取最大,然后再区间与 \(v\) 取最小(如果这么写祝你调得出来)。

没了。

\(T9\) BZOJ4695 最假女选手

吉老师线段树的前置操作混合,板题,不写。

祝调得出来,我没调处来翻了 tlq 然后发现也有人调不出来然后建议根据 oi-wiki 重构然后我也去重构了。。。

\(T10\) [JSOI2008] Blue Mary 开公司

李超线段树的另一个模板,但是有点变化的是题目给你的信息。

首先给你的信息可以抽象为一条在函数图上的一次函数,并且是直线,所以我们直接插入直线,而非插入线段。

然后题目给你了第一天的收益,以及每天的增长量。

对应 \(y = kx + b\),我们可以得到:

  • \(k\) 是题目给你的增长量。

  • \(x\) 是天数。

  • \(b\) 为题目给你的第一天的收益。

  • \(y\) 直接计算即可。

但是这个对吗?

注意到 \(x\) 不对,比如第二天的收益是 \(k + b\),第三天是 \(2k + b\),所以 \(x\) 应为天数 \(-1\)

然后跑李超线段树模板即可。

\(T11\) 对应模板:线段树 \(3\)(吉老师线段树),不写。

\(Day 8 \sim Day 9\) 数论专题

\(Day 8\)

\(T1,T2,T3,T4,T5,T6,T7,T8\) 对应模板:线性筛素数,有理数取余,exgcd,CRT,exCRT,乘法逆元 \(1\),快速幂,扩欧,裴蜀定理,不写。

\(Day 9\)

\(T1\) [SDOI2008] 仪仗队

自己一年前竟然能做出来?!

注意到一点:如果一个点 \((i ,j)\)(编号从矩阵最下角 \(0\) 开始),当且仅当满足如下任意一个条件才会被看见:

  • \(\gcd(i ,j) = 1\) 时,可以被直接看见,否则肯定会被一个 \(d | \gcd(i ,j)\)\(\gcd(\frac{i}{d} ,\frac{j}{d})\) 遮挡(手玩)。

  • \(i = 0, j = 1\)\(i = 1 ,j = 0\),很好理解,至于后面的都被他们两个挡住了。

那么要求的即为 \(\sum\limits_{i=1}^n \sum\limits_{j = 1}^n [gcd(i ,j) = 1] + 2\),注意特判 \(n = 0 ,1\)

然后我们发现有点难求,然后对照图片可以发现是对称的,那么我们可以把原式转化为:

\[2\times \sum\limits_{i=1}^n \sum\limits_{j = 1}^i [gcd(i ,j) = 1] + 2 \]

此时我们有两种选择,一是线性筛求欧拉函数,因为后面就是欧拉函数;二是莫比乌斯,但是这题还是欧拉直接一点,虽然莫比乌斯也很一眼。

\(T2\) GCD SUM

\[\begin{equation} \begin{aligned} \sum\limits_{i=1}^n\sum\limits_{j=1}^n \gcd(i ,j) &= \sum\limits_{d = 1}^nd\times \sum\limits_{i = 1}^n\sum\limits_{j = 1}^n [\gcd(i ,j) = d] \notag\\ &= \sum\limits_{d = 1}^n d\times \sum\limits_{i = 1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{j = 1}^{\lfloor\frac{n}{d}\rfloor}[\gcd(i ,j) = 1]\\ &= \sum\limits_{d=1}^n d\times \left(\sum\limits_{i = 1}^{\lfloor\frac{n}{d}\rfloor} \left(2\times \sum\limits_{j = 1}^i [\gcd(i ,j) = 1]\right) - 1\right)\\ &= \sum\limits_{d=1}^n d\times \left(2\times \sum\limits_{i = 1}^{\lfloor\frac{n}{d}\rfloor} \varphi(i) - 1\right) \\ \end{aligned} \end{equation}\]

然后线性筛欧拉函数然后前缀和就行了。

\(T3 ,T4\) 对应模板:Lucas,二次剩余,不写。

\(T5\) 上帝与集合的正确用法

扩欧的基本应用,用递归写即可,不多说了。

\(T6,T7\) 对应模板:原根,BGSG,不写。

\(T8\) [SDOI2013] 随机数生成器

BGSG 运用。

先咕咕了因为 KaTeX 过多。

\(T9\) 对应模板:Dirichlet 前缀和,不写。

(待补)\(Day 10\sim Day 11\):图论专题

\(Day 10\)

\(T2\) 对应模板:差分约束,不写。

\(T4 ,T5 ,T6 ,T7\) 对应模板缩点,割点,边双,点双,不写。

\(Day 11\)

又是没有 AK 的一天。

\(T4\) 对应模板:欧拉路径,不写。

\(T6 ,T7\) 对应模板:最小生成树,2-SAT,不写。

(待补)\(Day 12\sim Day 13\):树论专题

\(Day 12\)

\(T1\) [SDOI2013] 直径

第一问直接两 DFS / 树形 DP 就行,但是这边推荐两 DFS,因为后面有用。

然后考虑第二问怎么做。

我们把直径的端点记作 \(p\)\(q\)\(p\) 深度更浅,然后把 \(p\) 提起来作根,那么 \(p-q\) 就是一条节点到根的链了。

然后我们标记一下 \(p-q\)(直径)上的所有点。

接着我们对直径上的每个点跑一遍 dfs,记录一下节点不经过直径上的任意一个点能够到达的最远距离,记作 \(maxn_i\)

接着我们从 \(q\) 向上遍历直径的节点,设当前节点为 \(i\),如果 \(dis(i ,q) = maxn_i\),说明 \(i-q\) 不一定为直径,我们存在另一个路径。我们找到第一个满足此条件的节点,记作 \(cur\)

然后从 \(cur\) 往上遍历直径,如果发现 \(dis(p,i) = maxn_i\),我们可以把 \(p-i\) 这一条路径改为 \(p\)\(maxn_i\) 对应的这个端点。

然后如果不满足一直累加答案即可。

\(T2\) 【XR-3】核心城市

首先思考 \(k = 1\) 的情况,明显这时选直径中点一定最优,因为直径最长,选取中点可以平衡一点(感性理解)。

接着我们把直径中点提起来为根,然后计算每个节点距离它最远的节点的距离(不经过核心城市,下文省略),贪心想,我们取前 \(k - 1\) 大的一定最优。

然而条件一告诉我们这些核心城市必须相邻,我们选出来的城市一定相邻嘛?

答案是一定的,如果不选相邻的点选更大深度的点,容易发现更大深度的点能够到达的最远距离一定小于更浅的,因此这是正确的。

然后怎么求节点距离它的最远距离呢?我们可以用 \(mx_i\) 表示节点 \(i\) 能够不经过核心城市到达的最远节点的深度,\(dep_i\) 表示节点 \(i\) 的深度,那么这个距离就为 \(mx_i - dep_i\)

然后预处理一波排序就做完了。

\(T3\) [NOI2003] 逃学的小孩

明显把 A,B 放在直径两端最好,让家长极限拉扯。

然后枚举 C,找到最长的 \(\max(dis(A ,C) ,dis(B ,C)) + dis(A ,B)\) 即可。

\(T4\) 对应模板:LCA,不写。

\(T5\) 仓鼠找 sugar

一个结论题,证明略。

记询问为 \((a ,b ,c ,d)\)\(fa1 = LCA(a ,b)\)\(fa2 = LCA(c ,d)\)

我们记深度较大的为 \(fa1\),深度较小的为 \(fa2\)

也就是说,如果 \(dep_{fa1} < dep_{fa2}\),需要交换 \(fa1 ,fa2\)\(a ,c\)\(b ,d\)

然后如果 \(LCA(fa1 ,c) = fa1\)\(LCA(fa1 ,d) = fa1\),就是有交,否则没有。

具体证明蒟蒻难以解释,TJ 区也有点长,大概手玩就有点理解了。

\(T6\) [JLOI2014] 松鼠的新家

树上差分真板子。

这边是点差分,所以让 \(fa_{lca}\)\(lca\) 减一,\(u\)\(v\) 加一。

然后 dfs 推出数量就行。

然而由于 \(a_1 - a_2\) 会把 \(a_2\) 加一遍,\(a_2 - a_3\) 又会把 \(a_2\) 加一遍,以此类推,\(2\sim n\) 都重复增加了一遍。

因此这些答案都减一就行。

\(T7\) [NOIP 2013 提高组] 货车运输

直接建 Kruskal 重构树啊,没啥好写的。

\(T8\) [USACO18FEB] New Barns P

有个很强的关于直径的性质:

  • 如果两棵树 \(T1\)\(T2\) 用一条边连起来且还是一棵树,那么这颗大树 \(T\) 的直径端点,一定在 \(T1\)\(T2\) 的直径端点中。

然后这里是新建一个节点 \(idx\),记原树的直径端点为 \(x ,y\),那么总共可能产生三条可能直径:

  • \(idx - x\)

  • \(idx - y\)

  • \(x - y\)

然后还有一个性质:

  • 一个点出发能够到达的最远距离的节点一定是直径端点中的一个。

然后可以用并查集维护树的直径,然后怎么维护直径间的距离呢?

这时用 LCT 大法就行了,split 出来然后用子树大小减一即可(因为求的是距离所以减一)。

\(T9\) [NOIP 2015 提高组] 运输计划

树上差分题。

首先答案呈单调性,容易想到二分答案。

那么我们二分这个最短时间,有了这个最短时间 \(mid\) 我们可以搞出什么呢?

首先遍历左右运输计划,然后对于运输计划上的每条边:

  • 不大于 \(mid\) 的路径肯定不修改,不然明显更劣。

  • 大于 \(mid\) 的路径要修改,非常显然,我们记录这种边的个数为 \(x\)

特别地,如果 \(x = 0\) 那么答案肯定更小,这时不用修改。

然后考虑我们需要哪条边给予幸运的虫洞,难道是随意嘛?

不,我们要把虫洞放在经过次数为 \(x\) 的有效边

为啥?

如果不修改经过次数为 \(x\) 的有效边,那么肯定存在另一条 \(> mid\) 的有效路径,那么肯定更劣。

所以让这条边的 \(t\gets 0\)(也就是用了虫洞),再判断现在最大的运输路径长度是否 \(\le mid\),是答案可以尝试更小,否则只能更大。

注意可能不止一条,不要太心急。

那么怎么计算虫洞影响后,最大的运输路径长度呢?

我们记录一开始最长的运输路径长度为 \(mxlen\)\(dis\) 为可以改为虫洞的边的距离,那么最长的虫洞影响后的路径长度一定是 \(mxlen - dis\),很好理解。

那么怎么计算边的出现次数呢?

直接用边差分就行了,\(u\)\(v\) 都加一,\(lca\) 减二。

剩下的路径长度用 LCA 即可。

\(T10\) Deception Point

明显这是一棵基环树,那么这棵树只有一个环。

也就是说,先手只要足够提前到达这个环,就能绕环逃脱,因为环节点的个数至少为 \(5\)

那么就好做了,首先拓扑找环,然后对于环上每个点进行 dfs 统计这些点到离环最近的节点的距离,然后对于询问 \((x ,y)\)

我们记 \(x\) 到达的最近环上点为 \(x'\)\(y\) 同理为 \(y'\)

然后到的距离分别为 \(tx\)\(ty\)

  • 如果 \(tx < ty + dis(x' ,y')\),那么先手可以逃脱,在充足时间内可以往相邻的节点跑,等后手逼近时绕环。

  • 如果 \(tx \ge ty + dis(x' ,y')\) 时,后手可以抓到,显然。

这题就做完了,也是非常简单好吧自己都能做出来(虽然发了求调帖不过不重要)。

\(T11\) 部落冲突

还记得那时是用线段树分治做的,结果空间开太小 MLE 了。

现在一看就是 LCT 板子。

  • 操作 \(1\),我们只要判断 findroot(p)findroot(q) 是否相等就行了。

  • 操作 \(2\)cut(p ,q) 就行。

  • 操作 \(3\)link(p ,q) 就行,\(p\)\(q\) 是第 \(x\) 场战争的两个部落编号。

中间休息了一天。

\(Day 13\)

又是没 AK 的一天。

\(T1 ,T2\) 对应模板:树上 \(K\) 级祖先,prufer 序列模板,不写。

\(T3\) [HEOI2014]大工程

明显每次询问给出 \(k\) 个点,这就是提醒我们建虚树。

首先考虑怎么计算和,我们改变一下策略,计算每条边的贡献为:权值乘贡献次数。

\(sz_u\)\(u\) 的字数中关键点的个数,\(point\) 为关键点的总个数,那么对于一条边 \((u ,v)\),贡献次数为 \(sz_v \times (point - sz_v)\),然后权值是 \(dep_v - dep_u\)(两点之间的深度),累加即可。

对于代价最大/最小值,我们记录点 \(u\) 子树的最大/最小路径长度和次大/次小路径长度,然后以点 \(u\) 作为连接点比较最大/最小值即可。

\(T4\) 生成树

prufer 序列应用。

明显每一条边的出现次数都是相等的,记作 \(c\)

我们考虑怎么计算 \(c\)

首先因为一个 prufer 序列都可以对应一个新的树,那么一个完全图就有 \(n^{n - 2}\) 个生成树。

一个生成树边数为 \(n - 1\),而完全图中有 \(\frac{n(n-1)}{2}\) 条边,平均计算就是:

\[c = \frac{n^{n-2}(n-1)}{\frac{n(n-1)}{2}} = \frac{2(n-1)n^{n - 2}}{n(n-1)} = 2n^{n - 3} \]

因为一条边的边权为 \(a_i\oplus a_j\),所以题目其实让我们求:

\[c\times \sum\limits_{i = 1}^n\sum\limits_{j = i + 1}^n a_i\oplus a_j \]

后面这一个式子是个套路的做法,拆位计算即可。

\(T5 ,T6\) 对应模板:点分治(淀粉质),点分树(淀粉树),不写。

\(T7\) (待补)[NOI2021]庆典

\(T8\) [NOI2015]软件包管理器

直接上以前写的专栏里的内容,顺便偷点懒。

『没有环』提示我们这是一棵树。

考虑把当前为安装状态的看成 \(1\),当且为不安装状态的看成 \(0\)

  • 安装(install)操作:只会改变其祖先当前状态为『没有安装』的节点,因此答案为根到节点状态为 \(0\) 的个数。输出后都覆盖为 \(1\) 即可。

  • 卸载(uninstall)操作:只会改变其子树内节点当前状态为『安装』的节点,因此答案为子树内状态为 \(1\) 的个数。输出后都覆盖为 \(0\) 即可。

然后就是区间覆盖 + 求区间 \(0/1\) 个数的板子,用重剖辅助即可。

时间复杂度为 \(\mathcal O(Q\log^2 n)\)

\(T9\) 对应模板:重链剖分,不写。

\(T10\) [AHOI2008] 紧急集合 / 聚会

考虑到三个树上的点,两两组合的 LCA 必然有一个重复,证明手玩就行,玩遍所有情况即可。

然后可以发现选取它们三个点两两组合的 LCA 中的一个肯定更有,不然一定更劣,想想都知道。

问题是选三个中哪个 LCA。

  • 如果三个都相等,没得选。

  • 如果两个相等,那肯定取不重复的那个,手玩发现重复那个 LCA 一定是三个中深度最浅的,那么走起来花费会更多。

然后求出这个最优点,计算一下距离总和就行了。

\(T11\) [蓝桥杯 2023 省 A] 颜色平衡树

一眼 DSU on tree,但是难点在于如何判断子树合法。

我们可以记录子树的颜色种类数 \(num\),以及每种颜色出现次数 \(cnt_i\),还有出现了 \(i\) 次的颜色个数 \(colcnt_i\)

我们记 \(u\) 为当前子树的根,记 \(u\) 的颜色为 \(color\)

如果有 \(num\) 种不同的颜色,出现了 \(color\) 的出现次数,那么这个子树就是合法的,即 \(colcnt_{cnt_{color}} = num\)

清楚了这个就直接 DSU on tree 即可。

(待补)\(Day 14\):组合数学专题

\(Day 14\)

\(T1\) 高维立方体

俺有差点 AC 的绿了!

这种四维和五维等的都想不到,是个人都先打表。

\(0\)(y$) \(1\) \(2\) \(3\)
\(0\)\(x\) \(1\) \(0\) \(0\) \(0\)
\(1\) \(2\) \(1\) \(0\) \(0\)
\(2\) \(4\) \(4\) \(1\) \(0\)
\(3\) \(8\) $12 $ \(6\) \(1\)

然后发现 \(f_{x ,y} = f_{x - 1 ,y - 1} + 2f_{x - 1 ,y}\)

这玩意儿就是比杨辉三角的递推式第二项多了个系数 \(2\) 而已,有数学知识的就知道这是 \((a + 2)^x\) 展开项的 \(a^y\) 项系数。

然后二项式定理:

\[(a + b)^n = \sum\limits_{k = 0}^n \binom{n}{k} a^{n - k} b^k \]

代入 \(a = x\)\(b = 2\),那么 \(b\) 次方项对应 \(k = n - y\),系数就为 \(2^{x - y}\binom{x}{x - y} = 2^{x - y}\binom{x}{y}\)

\(T2\) [AHOI2012] 树屋阶梯

一年前 yrl 让做的。

打表出来就是卡特兰数,证明 TJ 里有,就是运用

\[C_n = \sum\limits_{i = 0}^{n - 1} C_i C_{n - i - 1} \]

的这个递推式,然后随便取一个 \(n\) 写一下过程就行。

\(T3\) [HNOI2009] 有趣的数列

俺有自己 AC 的绿了!

打表卡特兰,这稍微转化一下就是个很典的卡特兰例子了。

但是高精复杂度太高,python TLE,一群没用的东西。

但是这题是取模,但 \(p\) 不一定是质数,可能有的数没有逆元,舍弃公式 \(C_i = \frac{C_{i - 1}\times (4n - 2) }{n + 1}\)

但是我们卡特兰还有一个公式,就是 \(C_n = \frac{\binom{2n}{n}}{n + 1}\)

展开来就是

\[C_n = \frac{\binom{2n}{n}}{n + 1} = \frac{2n(2n - 1)(2n - 2)\dots(n + 2)(n + 1)}{n!(n+1)} = \frac{2n(2n - 1)\dots(n+2)}{n!} \]

这就是一个很套路的问题了,把每个数分解质因子然后做就可以了。

具体地,用一个数组记录每个质因子的出现次数,初始先让除数初始化为 \(-1\)\(1\sim n\)),乘数初始化为 \(1\)\(n + 2\sim 2n\))。

然后把贡献传给自己(设为 \(x\),且必须为合数)最小的质因子 \(p\) 以及 \(\frac{x}{p}\),这样有正确性证明,也可以纸上手玩感性理解(就是以前的我)。

然后唯一要求的:求出每个数的最小质因子。这玩意儿直接线性筛就行。

\(T3\) [YDOI R1] Necklace

俺有自己 AC 的绿了!

既然直接算有点难,我们考虑对于每一串,\(v_i^{cnt_i}\) 能贡献多少个不同串。

明显其他的串每个都能随便选或不选,我们记 \(all\)\(\sum a_i\),那么能够贡献 \(2^{all - a_i}\) 个不同的串。

那么问题就转化为求:

\[\sum\limits_{i = 1}^n 2^{all - a_i} \times \sum\limits_{k = 1}^{a_i} \binom{a_i}{k} v_i^k \]

现在我们只要求这个,其他都是小儿科:

\[\sum\limits_{k = 1}^{a_i} v_i^k \]

注意到这个很像二项式定理,直接代入 \(a = v_i ,b = 1\) 直接算就行。

但是二项式定理是从 \(0\) 开始的,没关系,我们把 \(0\) 代入:\(\binom{a_i}{0} v_i^0 1^0 = 1\)

所以这一堆式子就是 \((v_i + 1)^{a_i} - 1\)

那么只要求出 \(\sum\limits_{i = 1}^n 2^{all - a_i} \times \left(\left(v_i + 1\right)^{a_i} - 1\right)\) 就行了。

\(T4\) 「2.48sOI R1」猜数

额,要不是以前有个同学给我玩这个玩意儿我可能连 \(m\) 的值都想不到。

首先把每个数放在二进制下,然后这样放卡片;

  • \(0\) 位为 \(1\)

  • \(1\) 位为 \(1\)

  • 以此类推。

容易发现 \(0\) 不影响,如果全是 \(0\) 答案自然是 \(0\)

\([1 ,n]\) 中二进制位数最多的肯定是 \(n\),然而 \(n\) 的二进制位数是 \(\lceil \log_2^{n + 1} \rceil\),题目善良,给你的是小于 \(n\),那么 \(m = \lceil \log_2^{n} \rceil\) 了。

容易发现这个就是最少的方法。

然后来尝试解决问题。

考虑到一个数在这么多卡片中的出现情况有 \(2^m\) 种,\(n\) 个数字要选做排列,方案数为 \(A_{2m}^n\)

但是卡片顺序不同但是卡片本质相同算一种方案,所以答案为 \(\frac{A_{2m}^n}{m!}\)

\(T6\) [SDOI2016] 排列计数

首先选 \(m\) 个位置作为不改变的位置(幸运儿),方案数为 \(\binom{n}{m}\)

然后剩下 \(n - m\) 个位置需要错排,方案数为 \(d_{n - m}\)

根据乘法原理,总方案数为 \(\binom{n}{m} d_{n - m}\)

我都不相信这么简单,但是事实如此,建议降黄。

\(T7\) [ICPC 2020 Shanghai R] Mine Sweeper II

以前土 0 的模拟赛 T1,没做对。

首先如果 A 和 B 相差不到 \(\lfloor\frac{nm}{2}\rfloor\) 答案就是 A。

否则 A 的反图(.XX.)一定与 B 差异小于这个式子。

然后容易手玩 / 证明 A 的反图非雷数字格和 A 一样,这时答案就是 A 的反图了。

\(T8\) [USACO18DEC] Cowpatibility G

容斥原理入门。

不能和谐共处的奶牛我们不求,我们只要求出能和谐共处的奶牛对数,然后用总对数 \(\frac{n(n - 1)}{2}\) 减去它就行了。

然后可以和奶牛 \(i\) 和谐共处的奶牛数量 \(= \sum\limits_{k = 1}^5 (-1)^{i + 1} \text{和} i \text{有} k \text{个相同的的奶牛数量}\)

直接 map 做就行了,当然选取的过程不嫌累可以直接每种情况打一遍,嫌累像我直接暴力,或者也可以 dfs。

还有为什么要用 tuple?!直接结构体不香嘛。

\(T9\) [JSOI2013] 游戏中的学问

我们设 \(f_{i,j}\) 为前 \(i\) 个人围成 \(j\) 个圈的方案数。

那么转移:

\[f_{i ,j} = (i-1)\times f_{i - 1 ,j} + (i-1)(i-2)\times f_{i - 3 ,j - 1} \]

  • 前面的表示 \(i\) 加入已经有的圈中,可以有 \(i - 1\) 个位置插,因为空位数量就是圆圈人数总和,根据乘法原理就是 \((i - 1) \times f_{i - 1 ,j}\)

  • 后面的表示 \(i\) 自己围成一个圈,但是题目要求两个不同人的手,所以可以随机选取两个幸运儿作为自己的左手和右手,方案数为 \((i - 1)(i - 2)\),根据乘法原理就是 \((i - 1)(i - 2) \times f_{i - 3 ,j - 1}\)

  • 根据加法原理把它们相加就行了。

然后没了。

\(T10\) SAC #1 - 组合数

简单题。

根据组合数的性质:

\[\sum\limits_{k = 0}^n \binom{n}{k} = 2^{n} \]

直接代就行。

证明用二项式定理,代入 \(a = b = 1\) 即可。

然后我们还有性质:

\[\sum\limits_{k | 0\le k\le n ,k \bmod 2 = 0}^n \binom{n}{k} = \sum\limits_{k | 0\le k\le n ,k\bmod 2 = 1}^n \binom{n}{k} \]

证明就是根据二项式定理代入 \(a = 1\)\(b = -1\),得到:

\[\sum\limits_{i = 0}^n (-1)^i \binom{n}{i} = 0 \]

然后两个式子相加:

\[\sum\limits_{k = 0}^n \binom{n}{k} = 2^{n} + \sum\limits_{i = 0}^n (-1)^i \binom{n}{i} = \sum\limits_{k | 0\le k\le n ,k\bmod 2 = 0}^n 2\times \binom{n}{k} = 0 + 2^n = 2^n \]

所以

\[\sum\limits_{k | 0\le k\le n ,k \bmod 2 = 0}\binom{n}{k} = \frac{2^n}{2} = 2^{n - 1} \]

那么

\[\sum\limits_{k | 0\le k\le n ,k\bmod 2 = 1} \binom{n}{k} = 2^n - 2^{n - 1} = 2^{n - 1} \]

没了。

\(T11\) [HNOI2012] 排队

这是真纯数学。

首先分情况讨论:

  • 老师中间有男生。

那么男生有 \(A_n^n\) 种排列,老师插入 \(n + 1\) 个空中,方案数 \(A_{n + 1}^2\),然后 \(n + 3\) 个空插入女生,方案数为 \(A_{n + 3}^m\),答案为:

\[A_n^n \times A_{n + 1}^2\times A_{n + 3}^m \]

  • 老师中间只有一个女生

男生有 \(A_n^n\) 种排列,两个老师插入 \(n + 1\) 个空中的其中一个,然后可以全排,方案数为 \(A_2^2 (n + 1) = 2(n + 1)\),然后捆绑两个老师和一个女生,这个女生随便选,有 \(m\) 种,再将 \(m - 1\) 个女生插入 \((n + 1) + 1 = n + 2\) 个空,方案数为 \(A_{n + 2}^{m - 1}\),答案为:

\[A_n^n \times 2(n + 1) m\times \times A_{n + 2}^{m - 1} \]

那么总方案数相加即可。

注意高精或者 python 大法。

\(Day 15\):博弈论专题

\(Day 15\)

\(T1\) 谁能赢呢

二分图博弈。

二分图博弈可以抽象为:一个石头被放在二分图的一个点上。两人轮流移动石头。每一回合,选手只能把石头向上,下,左,右四个方向移动一格,并且要求移动到的格子之前不能被访问过。谁不能移动石头了就算输。

然而我们题目要求的棋盘就是二分图,感性理解就是不存在奇环。

然后二分图博弈的结论:

若该二分图的最大匹配一定包含起点,那么先手必胜;否则先手必败。

证明不会。

然后手玩可以发现,当 \(n\) 为偶数时,最大匹配一定包含左上角;而 \(n\) 为奇数就不一定了。

具体可以黑白染色画出二分图然后试试。

然后就做完了。

\(T2\) 黑白棋(2021 CoE-II B)

我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM 我竟然没看出这是 NIM。

当黑棋和白棋相邻时,另一方动不了。

因此我们把(黑棋与白棋 \(x\) 坐标的绝对值减 \(1\))看作一堆石子的个数,然后我们可以一直减少两颗棋子的距离,也就是可以拿走这一堆石子若干的数量,这就是经典的 NIM 游戏。

但是我们想到题目还有回退操作,但是如果一个人用了回退另一个人可以前进抵消掉回退,所以回退无用。

然后做一遍 NIM 游戏的结论即可。

\(T3\) 欧几里得的游戏

对于一个组合 \((a ,b)\),我们记 \(a = kb + r\),其中 \(b = \lfloor\frac{a}{b}\)\(r = a\bmod b\)

那么我们可以通过减任意倍到下一个状态 \(((k-1)b + r ,b)\)\(((k-2)b + r ,b)\)\(\dots\)\((b + r ,b)\)\((r ,b)\)

然而当 \(k \ge 2\)\((a ,b)\) 为必胜态,证明:

  • 如果 \((r ,b)\) 为必胜态,而 \((b + r ,b)\) 只能转化到 \((b ,r)\),因此 \((b + r ,b)\) 是必败态,因为下一步先手是必胜态,然后可以往上类推得到 \((a = kb + r ,b)\) 是必胜态,因为我们可以转化到 \((b + r ,b)\) 使得后手变成必败态(这里可以看出 \(k \ge 2\) 是必须的——。

  • 如果 \((r ,b)\) 是必败态,那么 \((a = kb + r ,r)\) 一定是必胜态,我们可以直接一步操作让后手变成必败态。

那么当 \(k = 1\) 呢?

  • 如果 \(a = b\),那么显然先手必胜。

  • 否则只有一个状态,直接计算出新状态继续递推即可。

这题就成模拟了。

\(T4\) 伊甸园日历游戏

显然必胜态是 \((2006.11.3)\)

然后对于每个点都有它的后继状态,明显这个图是 DAG。

然后只要计算每个点的 SG 函数值即可,就能做到 \(\mathcal O(1)\) 查询。

\(T5 ,T6\) 对应模板:NIM 游戏,阶梯 NIM 游戏,不写。

\(T7\) 对应模板:威佐夫博弈,不写。

\(T8\) 「ALFR Round 7」T2 Game

我还很清楚记得那天我打这个比赛只对了 \(T\) 是奇数然后只有 \(5\) pts。。。

差点研究出来。

首先 \(T\) 是奇数显然:

  • 先手要把第一个 \(a_i \neq i\) 的位置叫换成 \(i\),如果没有选择 \(i = j\)

  • 后手有两种选择:

    • 不交换会 \(i\)
      • 但是这样明显更劣,先手继续交换下一个满足 \(a_i \neq i\) 的,如果没有选择 \(i = j\),这样后手又回到了前面,但是字典序肯定更小了。
    • 所以后手不得不交换回 \(i\)
      • 先手:
        • 不交换回:跟下面同理。
        • 交换:明显不劣。所以先手一直选择这么做。
      • 但是操作次数是奇数,先手最后还能动一次,所以此时只要找到第一个满足 \(a_i\neq i\) 的直接交换输出就行。

然后 \(T\) 是偶数比较复杂。

  • 如果先手一开始交换第一个 \(a_i\neq i\),后手肯定会交换回来,然而因为 \(T\) 是偶数,最后一步是后手,所以这样动了和没动一样。

然后我们分情况讨论:

  • \(a_1 = n\),此时先手如果不换 \(a_1\),后手就会把更大的换上来,由于后手执行最后一步所以肯定不优。
    • 所以先手一定会把 \(a_1\) 换走,此时后手希望字典序更大又会换回来,先手再换回来,以此类推,最后后手执行,所以序列不变。
  • \(a_1\neq n\)
    • 此时如果先手换走 \(a_1\) 为更小的数,后手就会把 \(n\) 换上来,重复这样以此类推,答案肯定不优。
    • 所以先手不能从 \(a_1\) 入手,要从后面的数入手,如果后面的数(也就是 \(2\sim n\))的数都是递增的,先手一定会换走第一个使得后面不递增的数,也就是换走第一个 \(a_i\neq i - 1\) 的数换为 \(i - 1\)
    • 然后我们从后手的角度考虑,后手一定会把 \(n\) 换上来,因为先手如果再换走,后手还是可以换上来,\(\text{偶数} - 2\) 还是偶数。
    • 然而后手把 \(n\) 换上来可能也正好让先手的一个 \(a_i \neq i - 1\) 换成 \(i - 1\),因此先手可以不动这个动下一个 \(a_i \neq i - 1\) 的。
    • 然后先手和后手肯定是互相僵持的状态,先手换走 \(n\) 后手换回来,不然先手肯定不优。

然后没了。

这种东西随便画一个跟你的同桌玩可能就有灵感了。

\(T9\) [常州市赛 2024] 游戏

感觉绿有点虚高了?

注意到小 H 的优势可能有点多,我们从小 Y 入手。

小 Y 为了让这个序列不回文,极端情况下就是最后只剩 \(2\) 个数,这 \(2\) 个数不能相等。

所以小 Y 肯定会消去出现次数大于 \(1\) 的数。

那么小 H 就会尽量保留两个相同的数。

然而小 Y 只能删 \(\frac{2n - 2}{2} = n - 1\) 次。

我们记删除次数为 \(del\),如果 \(del \le n - 1\) 就是小 Y 获胜,否则就是小 H 获胜。

然后考虑中途是回文序列的情况。此时小 Y 又到了先手,设他删了 \(x\)

由于一个长度为偶数的序列删除了偶数次(\(2\times \text{轮数}\)),所以此时的序列长度仍然是偶数。

那么小 H 就能再删除一个 \(x\),就这样一直模仿小 Y,最后还是会得到两个相等的数(显然),所以可以按照上面的情况讨论。

再考虑本身就是一个回文序列的情况,这个时候 \(del \ge n\),考虑 \(del\) 的最小值应该在 \(a = [1 ,2 ,3 ,3 ,2 ,1]\) 之类的回文序列,所以此情况会默认判断小 Y 输。

因此结论:如果 \(del \leq n - 1\),小 Y 胜;否则小 H 胜。

\(T10\) [蓝桥杯 2024 国 A] 最强策略家

明显 \(1\) 的个数是先增多后减少,因为越到后面小乔优势越大,

而明显小蓝肯定要尽量分散地摆放 \(1\),不让小乔一下就清光了。

为了让 \(1\) 最大化,小蓝考虑到自己一轮只能摆放两个 \(1\),而小乔一定会清除至少一个 \(1\),不然小乔一定更劣。

讲完这些我们好像没地方思考了,但是我们想到 \(1\) 的个数会突然减少,这个局数是呈单调性的,所以我们考虑二分这个轮数,找到第一个一定会使得 \(1\) 减少的轮的编号。

对于第 \(mid\) 轮,小乔就能清除 \(mid\times mid\) 的矩形内的 \(1\),然而小蓝不能再任意一个 \(mid\times mid\) 的矩形放多于 \(1\) 的数量的 \(1\),那么小蓝最多放置 \(\lceil\frac{n}{mid}\rceil^2\)\(1\),如果不理解为什么上取整可以手玩,这个有点抽象。

然后我们考虑如果前 \(mid - 1\) 轮最多有 \(mid - 1\)\(1\),加上这次能够放置 \(2\) 个,这一轮最多可以放置 \(mid - 1 + 2 = mid + 1\)\(1\)(小乔不清除的话)。

因此如果 \(\lceil\frac{n}{mid}\rceil^2\ge mid + 1\),说明小蓝还能摆放,二分右区间,否则二分左区间。

然后我们得到了这个编号,记作 \(ans\),小蓝在前 \(ans - 1\) 轮最多摆 \(ans - 1\)\(1\),然而这轮还能再摆 \(2\)\(1\),所以答案为 \(ans - 1 + 2 = ans + 1\)

(一题待记录)\(Day 16\):杂项

\(Day 16\)

\(T1\) 哈希冲突

根号分治入门题。

我们容易设计两种算法:

  • 暴力,不用多说,修改——查询是 \(\mathcal O(1) -- \mathcal O(m)\)

  • 用数组存,记 \(f_{x ,y}\) 为模 \(x\) 意义下为 \(y\)\(value\) 总和,那么对于一次单点修改权值,这个表要修改 \(n\) 次,因此修改——查询是 \(\mathcal O(m) -- \mathcal O(1)\)

等一下,我们能不能把它们均衡一下?

可以的,我们把模数分成前 \(B\) 个和后 \(B\) 个,前 \(B\) 个用方法二,后 \(n - B + 1\) 个用方法一,容易发现 \(B\)\(\sqrt{n}\) 就可以均衡,时间复杂度为 \(\mathcal O(m\sqrt{n})\)

\(T2\) [CSP-S 2022] 星战

额,就像评论里说的,就这么点思考东西但是就是想不到。

首先考验语文功底。

先罗列一下答案为 Yes 的条件:

  • 每个点只有一条出边。

  • 从任意一个点开始都可以无限走下去。

首先条件 \(1\) 告诉我们这是一棵内向基环树。

然后内向基环树必定满足条件 \(2\),因为可以从点一直走到内向基环树的环上(内向基环树的定义)。

然后我们可以维护点的出度,乱搞一通,期望得分 \(60\) pts。

正解是我们对每个点随机一个权值,记作 \(w_u\)。而对于一个节点 \(u\) 的点权记为终点为 \(u\) 的边的起点的边权之和,记作 \(val_u\)

下面分类讨论操作:

  • 操作一:删除一条边。
    • 记边为 \((u ,v)\),那么让 \(val_v\gets val_v - w_u\) 即可。
  • 操作二:删除以一个点为终点的所有边。
    • 记这个点为 \(u\),直接让 \(val_u\gets 0\) 即可。
  • 操作 \(3\):恢复一条边。
    • 同理直接让 \(val_v \gets val_v + w_u\) 即可。
  • 操作 \(4\):恢复以一个点为终点的所有边。
    • 同上,直接让 \(val_u\) 变为初始\(val_u\) 即可。

这个很好理解。

那么什么时候每个点只有一个出边呢?

当且仅当 \(\sum w_u = \sum val_u\)

为什么呢?

  • 如果有点的出边数量为 \(0\),那么这个点的权值无法贡献到。

  • 如果有点的出边数量大于 \(1\),那么这个点的权值会贡献多次。

因此正确,这也告诉我们随机化的原因:为了防止小的数求和时正好相等从而得到错误答案。

因此我们还有维护两个动态变量记录 \(w\)\(val\) 的和,这题就没了。

\(T3\) [SEERC 2018] Modern Djinn

随机化题。

题面有点问题,建议看讨论区。

做法是随机给每个点黑白染色,然后判断是否可行,如果不可行继续随机。

考虑一条边 \((u ,v)\) 什么时候满足条件,发现符合题意的就一种情况。

那么一条边就有 \(\frac{1}{4}\) 的概率成为有效边,因为你需要至少有 \(\lfloor\frac{m}{4}\rfloor\) 条有效边,所以概率近似,随机几次基本上就有结果了。

挺玄学我也是看了 TJ 好吧。

\(T4\) [CEOI 2015] 世界冰球锦标赛 (Day2)

一般可以搜索的 \(n\le 40\) 左右的都是折半搜索。

我们发现 \(n\le 20\) 很简单,但是 \(n\le 40\) 搜索却炸了。

因此我们考虑将序列分成前 \(B\) 个和后 \(n - B + 1\) 个,然后进行搜索,把统计到的答案再通过某些方式合并,最后得到答案。

对于这题,我们把两块分别进行 dfs 并把统计到的和记录 vector,最后统计答案用二分实现即可。

时间复杂度为 \(\mathcal O(2^B + 2^{n - B + 1})\),大概 \(B\)\(\frac{n}{2}\) 可以均衡。

\(T5\) [USACO2.2] 集合 Subset Sums

首先判断无解,如果 \(\frac{n(n+1)}{2}\) 为奇数必然无解,因为这样不可能使得两部分和相等。

然后我们可以算得每个子集的和为 \(sum = \frac{n(n+1)}{4}\)

然而我们只要凑出一个 \(sum\) 就可以自动让另一个也为 \(sum\)

因此问题转化为:求 \([1,n]\) 的正整数有多少个方案使得和为 \(sum\)

这就是折半搜索模板了,直接套就行了。

\(T6\) [国家集训队] 小 Z 的袜子

莫队简单题。

考虑总方案数为 \(\binom{n}{2} = \frac{n(n+1)}{2}\),而袜子出现的概率为袜子相同的数量 除以 方案数。

所以只要求出袜子相同的数量就行了。

很显然直接离线然后莫队就行了。

当然 \(L = R\) 需要输出 0/1

\(T7\) [HNOI2010] 弹飞绵羊

我们先对序列进行分块处理。

然后记 \(jump_i\) 表示第一次跳出 \(i\) 所属的块的步数,\(pos_i\) 表示跳出后的落地点。

操作一直接 \(\mathcal O(\sqrt{n})\) 暴力跳即可。

操作二就是修改,容易发现只会更改块内信息。

因此我们倒序修改块内的信息,记 \(k_i\) 为弹力装置 \(i\) 的系数,\(block\) 为块编号:

  • 如果 \(j + k_j > r_{block}\)\(jump_j\gets 1\)\(pos_j \gets j + k_j\)

  • 否则,\(jump_j \gets jump_{j + k_j} + 1\)\(pos_j \gets pos_{j + k_j}\)

我们发现倒着更新就不用暴力跳了,这样时间复杂度为 \(\sqrt{n}\)

然后建块也跟上面同理,时间复杂度为 \(n\sqrt{n}\)

我自己几个月前都会做,这题感觉紫有点虚高了。

\(T8\) 「XSOI-R1」区间操作 (opt)

这题一眼 \(\mathcal O(n^2)\),但是发现在线有点问题,于是考虑离线。

然后我打了离线,结果 TLE,常数过大,不得不看着 TJ 重构代码。。。不会黄题

具体地,相同的左端点可以按照询问右端点 \(\mathcal O(n)\) 做,而最多有 \(n\) 个右端点,时间复杂度为 \(\mathcal O(n^2)\)

重构的时候发现 vector 码量短并且好写,根本不用看 TJ 都能自己写出来那种,这边推荐 vector 呀。

\(T9\) 寒假作业

以前一道模拟赛题,很套路的做法,那次有没有 AC 忘了。

首先把 \(\forall a_i\gets a_i - k\),问题转化为有多少个区间的和大于 \(0\)

然后再记录一遍前缀和,问题转为有多少个 \(i ,j | 1\le i\le j\le n ,pre_j - pre_{i - 1} > 0\),即 \(pre_{i - 1} < pre_j\)

我们继续等价转化为 \(i ,j | 1\le i < j ,pre_j - pre_i > 0\) 以及 \(i | 1\le i\le n ,pre_i > 0\) 的个数总和。

直接 BIT 维护即可,但是 TJ 区大佬竟然用 CDQ 感觉多余了,二维偏序用 CDQ 感觉就是装。

\(T10\) [USACO09NOV] Lights G

什么折半搜索?!这题我学的是高斯消元!!

考虑到开关最多点 \(1\) 次,不然点了跟没点一样。

我们又观察到 \(1\le n\le 500\),然后又是类异或题,想到高斯消元求异或方程组。

对于第 \(i\) 个方程,左边列方程,右边表示最终状态。

显然这些方程的右边都是 \(1\),我们记 \(x_i\) 表示点灯 \(i\) 的次数,那么左边就是所有可以影响这盏灯的影响。

比如 \(2 ,3 ,5\) 影响 \(1\),可以写作 \(x1 \oplus x_2\oplus x_3\oplus x_5 = 1\),以此类推。

然后就做完了嘛?我一开始也是这么认为的,但是后来发现异或方程解完后还有自由元,而随便取自由元好像不太行?然后点开 TJ:(

发现需要 dfs 自由元的取值,然后累加贡献。

因为自由元可能比 \(20\) 大, 我们需要小小加一点剪枝,就是当前答案不小于最优答案就不用 dfs 了。

时间复杂度 \(\mathcal O(\text{玄学})\)

\(T11\) 加工生产调度

咕咕,先放题解好了,这边到时候再写起来。

模拟赛游记

\(Day 1\)

前一天听说是 JYA 心里暗爽,因为 JYA 肯定有签到。

JYA 出题。

T1 水,预估 \(100\)

T2 一眼可以二分,写了发现只有 \(35\)?原来还有一个 \(n\),于是想到以前某题堆的做法,意外觉得惊喜,于是 \(15 + 25 + 35 = 70\),然后苦想无果,直接开 T4。

T4 发现 \(\mathcal O(n^2)\) ez 啊,直接拿了 \(50\),但是特殊性质的 \(a_i = i\) 是啥鬼?从头到尾没有一个 \(a\) 出现过,可恶题面,预估 \(50\)

然后苦想了 \(30\sim 60 min\) 想如何计算 \(\max - \min = j - i\),始终不会(甚至都没想到正解的数据结构),于是开 T3。

T3 发现 \(20\) 很好拿,于是打了,然后听到旁边的 xxs 说 T3 他分治 \(40\)(然鹅结果保龄了),于是想分治半分钟觉得不可做,然后想 DP。

好像这时脑抽了看到 \(1\le n\le 300\) 和“中序遍历”没有想到区间 DP(wssb),预估 \(20\) 回去想 T2。

然后 T2 总结了一下堆和二分的做法,感觉可以合并在一起?然后在纸上画了一画感觉不可做,但是打了一点代码。

最后 \(5min\) 开摆。

预估 \(100 + 70 + 20 + 50 = 240\)

出分,但是只有 \(0 + 20 + 0 + 50 = 70\)

JYA PPT 上说一等线 \(220\),我甚至没有一等线的 \(\frac{1}{3}\)

我竟然都没有他们天天玩 CS/MC 或者刷抖音的高。

怒了,明天加油。

顺便推一波新写的 TJ

T1 水 T2 果然是二分和堆思想 T3 果然是区间 DP T4 竟然是扫描线(当然不是平面那个东西)!

气愤的是 T4 原本因为愚人节我找到了这题我想做的但是后来没做(奇怪)!

怒了/ll。

听说明天土 0,祝明天 $300 + $ pts(好像有点高 \(250\) pts 吧/doge)。

傍晚因为 CCR 上依旧 \(70\) 被 yrl 点名了,我就是懒。。。

\(Day 2\)

上楼发现 yrl 在土 0 旁边土 0 在打电话,然后讲个笑话:

然后就换成 CZM 了。。。

直接开 T1,一眼题,写了但是挂了,慌,开 T2。

然后整个机房吵得无比,实在忍受不了了,我心不静,读了 \(10\) min T2 还没读懂,直接开 T3。

然后 T3 感觉有点难,右上方的 xxs 说是差分还说 CZM 会在 T3 放这么简单的题,叫得很响,慌,后来说没看到 \(k\)

然后换种思路想答案,秒切,结果大样例 WA,慌。

没几分钟 CZM 上来改了 T3 大样例(fk),好不慌了。

然后开 T2,读了 \(N\) 分钟题目还没读懂。

正好他不小心发下来 checker,去康康,从 checker 看懂题意了。

然后一直肝 T2,换了 \(2\) 种写法,最终决定用 bitset 试试,实测菊花图的部分分 AC,其余的除了 \(n\) 小时全 \(-1\)。。。

考虑到这么复杂的式子肯定是算过的,我输出了 \(-1\),慌。

后来也有人看 SPJ 了,发现如果输出 \(-1\) 直接返回 WA。。。更慌了。

旁边的人:你这肝了一两个小时跟我们打菊花的一模一样。。。

竟然有人在问菊花是啥,还不止一个人。

中途我们发现 xyz 差分写挂了,于是我们一群人鼓励他写线段树(本来想鼓励他 LCT 的但是没人说),他竟然真的拿出深进开始 c 线段树了!!!

我们嘲讽他不会线段树,最后咋样我也不知道。

然后开 T1,思考了 \(10+\) min 然后切了,但是发现好像很水的样子。

在这 \(10+\) min 的过程中真是烦人,机房人看到 yrl 车子不在疯掉了,一群人搁那大喊大叫,气氛不太对。

好像 sjh 还是 yzy 为了造福玩 MC 的大众去插了几分钟网线我竟然知道的时候半分钟不到就拔了,亏了。。。

还有 \(1h+\),直接开 T4。

一眼不会,发现 \(k = 1\) 很简单,本来想打,觉得抓紧 \(1h\) 最后再打,先思考。

想了几分钟没想出来是因为把 - 以为是 \(k\le n\) 想了半天。

吐槽:为啥不用 ^ 啊我这几天给 yzy 干活编译表格都打 ^:(

然后旁边的人跟我说这个同于上面的表格,我一看最大只有 \(12\),一眼状压。

好像不够再设一维,好像还不方便我转移再射一维。

好了直接开写,但是发现还要跑 dijkstra 最多 \((2k + 1)\) 遍,慌,但是看到时限 \(3s\),不慌。

写完快结束了,中间出了点小插曲,忘记特殊边的边权了,不过没关系,还是极限过大样例啊。

机房已经疯掉了,都随意走动了随意提交随意改了,甚至 xxs 都交了两遍。。。

结果成绩已经导出了,这群人真的积极,fk,保龄了,OI 生涯这几年终于保龄一次了 555。

预估 \(100 + 30 + 100 + 100 = 330\),实际得分 \(0 + 0 + 0 + 0 = 0\)

不过没关系,还有 xyz 玩 CS 然后惹人生气电脑被关机了,代码没存 D 盘,最后二十分钟极限打代码 + C 别人代码。。。

什么你问那些 T4 \(68\) pts 咋做的?简单,出题人把所有题目的数据和 T1 std 发下来了,\(68\)\(4\) 个都是对着输入特判的输出。

最后是下午的订正,如果你点开 T4 你会发现大部分是 CZM 的 std,包括至少一半的 T2 也是 CZM 的 std。。。


中间休息一天。

\(Day 3\)

今天是 txy 的模拟赛,祝不要保龄。

首先开 PDF,竟然是反恐精英选拔赛,可是我不玩 CS,感觉看不懂题面,慌。

然后开 T1,没看到 \(9\times 9\) 的条件,虚想 \(2\) min。

然后轻松切了啊,用了 \(20\) min(我好菜)。

然后开大样例,发现 T1 数据都发下来了,还有 std!难怪听到别人在旁边好烦。

开 T2,发现暴力很好拿,想先打暴力,但是算了,现象正解。

想用线段树,但是发现合并不太好做。

然后想起来以前做题有个性质:一个数一直取模,每次取模后的数记作 \(v\),下一次取模比 \(v\) 小的数,一直这样做,\(x\) 变为 \(0\) 的次数约为 \(\mathcal O(\log x)\)

这就好做了,直接查找下一个比它小的位置就好了。

然后发现这个东西有点难做,花了 \(1\) min 想线段树,发现可以维护区间最小值,然后线段树上二分,时间复杂度两只 log,但是不慌,时限 \(3s\)

\(20+\) min 切了。

然后开 T3,感觉很水,直接到根就行,但是感觉不对,还是先打暴力再说,结果大样例 \(AND\) 全 WA。。。

硬瞪 \(N\) 分钟无果,不做了,开 T4。

然后发现 T4 有三个特殊性质,但是一眼 DP,开始设状态但是感觉有点难,DP 还要向上考虑。

发现 \(20\) pts 暴力,打了走人。

又发现 \(20\) pts 是区间覆盖问题,并查集打了走人。

然后 \(0\le w_i\le 1\) 感觉难做,不做了,\(40\) 走人。

回去看 T3,一直想不到代码哪错了。。。然后回去想 T4,想不到来 T3,循环看题。

然后结束了,上交文件,预期得分 \(100 + 100 + ? + 40 = 240 + ?\)

结果 yrl 让我交了两次,都是 \(0 + 0 + 0 + 0 = 0\)

然后这天我没去吃饭,研究为啥保龄,原来是我没写 return 0

www555www。

好了今天保龄了,NICE,连续第二天。

然后发 TJ,一眼出题人 T4 TJ AI 写的。。。

然后 T3 T4 竟然都是 DP,出题人偏 DP 是不是。

还有我知道为啥 T3 暴力都能挂,因为我把祖先当父亲了(wssb)。

T3 的 DP 方式挺特别的,以前没写过;T4 的 DP 方式也挺特别的,以前也没写过。

其实出题人把 T3 std 发下来了,但是我们这边没人敢 c。。。

总结就是没写过的问题(bushi。

但是我竟然 T4 部分分最高!

\(Day 4\)

今天竟然 Lmq 大佬出题,我帮 yzy 干活拿到了三张 Lmq 大佬签名!!!

好的开 T1,照常不会,写了 BFS,大样例不过,直接开 T2。

T2 竟然是数学题,稳了,直接草稿纸开推式子。

感觉写的有点复杂,不堪入目,所以先打了 \(\mathcal O(n^2)\),然后再打了 \(\mathcal O(n)\)。。。

然后回去看 T1,原来 \(i\) 打成 \(len\) 了,改完大样例过了。

去开 T3,感觉一眼题,但是觉得很奇怪,T3 这么简单?!

于是打了 DP,但是挂了。。。

虚空调试 \(N\) 分钟,无果,决定先开 T4。

T4 这些操作我一眼想到三元上升子序列那题,但是思考一下就部分分有点关系。。。

于是 \(40\) 部分分到手。

然后开想 \(Sub 3\)

一眼想到(假),然后打了,大样例不过!于是重新分析发现贡献不止一个。

懒得想了,所有人几乎都交了,去开 T3。

虚空调试终于给我过了 \(3\) 大样例,但是最后两个 WA。

然后怎么给我改的 \(2\) 个大样例 WA 了,不慌,还有 \(20\) min,大不了不要了,开 T4。

然后我从线段树角度想,感觉一眼正解?!(早知道不打部分分了),感觉 pushup 很板,于是打了。

最后极限过 T4 两个小样例,大样例不测了,因为就我没交,都在等我,好多人题解已经 C 好了就等导出后提交

等等这有啥反正 \(10:30\) 都交了有的都改过了,恼。

期望得分 \(100 + 100 + ? + 100 = 300 + ?\) 的成绩,最终也是获得了 \(0 + 0 + 0 + 0 = 0\) 的成绩啊。

原来我提交比 \(11:30\) 晚了几分钟,他们已经把成绩导出了。。。慌,可是 PDF 上写的 \(11:45:14\)(怪出题人?:())

什么你问为啥“好多人题解已经 C 好了就等导出后提交”,原来是因为 Lmq 走后开网了 \(24\) min 没人关网,大家 deepseek + 原题机直接人均 \(300 \sim 340\),我还以为某些入终于有出息了,逆天。

但是我竟然不知道没人跟我说!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

好吧我不是这种入:(不你就是

赛后看 T4 竟然是蓝题,我终于自己模拟赛 AC 线段树蓝题(其实以前都没有。。。)了 5555。

但是 T3 \(3\) pts 逆天,原来 Lmq 忘记 T3 开捆绑了嘻嘻(这条消息我发求调帖了但是帖子我删了),还有网传 Lmq 数据点很多竟然是真的。

\(Day 5\)

今天大恐龙模拟赛,感觉完了。

开 T1,一眼没看懂,没事,开 T2。

然后感觉 T2 哪里做过的样子,想了两种贪心,试了其中一种,发现大样例没过,另一种也不试了,打完直接开 T3。

T3 感觉还好,Q1 直接二分就行,Q2 逆天,看不懂样例为啥输出 \(2\)

然后胡了一下发现切 \(1\) 次也有一种情况,盲猜题目出错了,打了过小样例,测大样例,结果 Q2 输出 \(0\)。。。

然后回去 T1,又想了好久,点开大样例看输出发现诈骗,然后就想到做法,打完测大样例过了。

于是开 T4,发现 \(1\le n ,m\le 100\) 好做,\(300\) 不会。。。

然后发现全是糖果也很好做,打了走人。

后来想到长方形那题照样打了个单调栈,挂了,就过了两个小样例,后来不调了。

然后回去 T3,听 wcy 在后面大喊说有模数,然后我试了好多模数,\(998244353\)\(1000000007\)……每一个对的。

快结束了,我一眼瞄竟然 Q2 只有 \(4k+\),我还以为 \(4w +\)。。。

然后直接测试模数 \(10007\),发现过了大样例,直接提交。

预期得分 \(100 + ? + 100 + 36 = 236 + ?\),T2 随缘,发现我这种假掉的贪心 \(n / p\) 小还是可以过的。

结果实际得分 \(100 + 20 + 0 + 36 = 156\),洪文,今天有是没去吃饭的一天,研究为啥 T3 保龄。

然后观察我的转移方程好久(我菜),发现可以滚动数组,滚动了,交了尼姑,果然不 MLE 了?

然后回去瞪了好久,发现有个地方没取模,这时网已经开了,然后在尼姑原题上提交 A 了。

洪文,史上离 T3 T4 正解最近的一集却 AC 不了,wssb。

笑话:考前 D_S 和 xyz 一直爆破 TJ 密码,试了好几个人 AK IOI 都没试过,结果密码是键盘上乱敲的。

\(Day 6\)

不想写一点,感觉能够 \(200+\) 结果 \(20\),比 \(Day 1\) 还低,实际分数约为预估分数的 \(\dfrac{1}{10}\sim \dfrac{1}{14}\)

好吧还是写好了,见证一下全班倒数第三的记录。

posted @ 2025-08-01 16:58  2021zjhs005  阅读(27)  评论(0)    收藏  举报