2025.10.4 - 10.19
Question 1. [CTS2019] 氪金手游
有 \(N\) 种卡牌,第 \(i\) 种卡牌按照 \(W_i\) 为权重的概率抽到,即 \(P(i) = \dfrac{W_i}{\sum_j W_j}\),其中 \(W_i\) 按照 \(p_{i,1},p_{i,2},p_{i,3}\) 的权重取 \(1,2,3\)。
决定完所有的 \(W_i\),然后不断按照 \(W_i\) 的权重抽卡,直至每一种卡牌都被抽到至少一次为止。
设 \(T_i\) 表示第 \(i\) 张牌第一次抽出的时间,给出 \((N-1)\) 条限制,每一条限制要求 \(T_{A_j} < T_{B_j}\),其中 \((A_j,B_j)\) 忽略方向是树形结构。
求满足限制的概率。
\(N\leq 1000\)
首先我们考虑强制钦定树为以 \(1\) 为根的外向树,如果是这样的话,那么每个点 \(u\) 都要在它的子树中第一个取出。
假设考虑到其中的 \(u\) 子树,\(u\) 子树的 \(W\) 和为 \(S_u\)。
第一次取出根,概率为 \(\dfrac{W_1}{S_1}\),接下来分裂出若干棵子树,每个子树也是类似的 \(\dfrac{W_u}{S_u}\),证明:
钦定出 \(u\) 子树内在第 \(k\) 次取出 \(u\) 节点,对 \(k\) 无穷求和:
由等比数列无穷求和得原式。
现在我们将问题变化为:
- 给定一棵树,树上每个点的 \(W\) 可以赋权 \(1,2,3\),求所有情况所有子树 \(\dfrac{W_u}{S_u}\) 的乘积的和。
每一种 \(W_u\) 的概率不要忘记用 \(p_i\) 求出,这个是容易用树上背包解决的,设 \(f_{u,k}\) 表示考虑到 \(u\) 内子树且 \(S_u = k\) 的概率即可。
如果有实际上的反向边,考虑 \(P(a\to b\gets c) = P(a\to b \qquad c) - P(a\to b\to c)\),后者直接带 \(-1\) 的系数即可,前者由于直接独立出去所以 \(f_{u,x}\times f_{v,y}\) 直接转移到 \(f_{u,x}\) 即可。【此处存疑】
时间复杂度为 \(\mathcal{O}(N^2)\)。
Question 2. 「JOI 2017 Final T5」绳
现有一根长度为 \(N\) 的绳子,每一个单位长度为一段,第 \(i\) 段的颜色为 \(C_i\),初始厚度为 \(1\),总共只有 \(M\) 种不同的颜色且每种颜色都出现过。
Kaho 将不断操作这根绳子使得绳子的长度为 \(2\):
- 假设当前的绳长为 \(L\),将当前绳子的左端点记为 \(0\) 点,随后每隔一个单位长度标一个新点,编号较前一个 \(+1\)。
- 选择标号在 \([1,L-1]\) 中的一个点 \(p\),将较短的一方对折到较长的一方之上,但要求将要重合的两个部分颜色相同。
- 在每次对折前,你可以将任何一个位置区间 \([p,p+1]\) 重新染色,代价是位于 \([p,p+1]\) 位置上的绳段厚度。
- 对折后,重合的绳段厚度叠加。
- 整个对折过程的代价是每一次操作代价的总和。
对每个颜色 \(c\) 求 \(f_c\):如果最终长度为 \(2\) 的绳子包含这个颜色,那么最小代价是多少?
\(N,M\leq 10^6\)
显然最终只有不超过两种颜色,如果只有一种的话显然要把不同的颜色都染成指定的颜色,若颜色 \(c\) 的出现次数为 \(b_c\),那么 \(f_c\) 可以取 \(n - b_c\)。
否则,一定包含两种颜色,首先容易发现由于染色需要数量的代价,相当于对每根叠在这里的线都染了一次,所以不如先染色再对折。
我们给出结论:除去首尾的极长颜色段外,每一个极长颜色段的长度都是偶数,证明:
- 充分性(给出构造):
- 先将首尾两段不断缩减 \(1\) 的长度直至段长为 \(1\)。
- 选靠近首段与尾段的一个长度为偶数的连续段(也即第二段),以该段中点为中心对折,随后首段与第三段的第一个重合,原第二段到达端点处,回到第一步。
- 最终两种颜色段数各 \(1\)。
- 必要性(反之无解):
- 假设中间的某一段长度为奇数。
- 易知这一段内不能选定对折中心,每一次对折必须在该段外,所以该段前后两段无法合并。
- 该段与某一段重合后,易知另一段长度与之相等(所以也为奇数),回到假设。
- 这样的段的前后两段永远无法合并,则绳长不可能达到 \(2\)。
有了这个结论,考虑用“相邻两个位置的位置相同”刻画每一段长度为偶数,存在两种位置划分“相邻的位置”:
- \((1,2),(3,4),(5,6),\cdots\)
- \((2,3),(4,5),(6,7),\cdots\)
显然分别做,在其中一种情况,假设要计算颜色 \(c\) 的答案,先将颜色 \(c\) 去除,再将与颜色 \(c\) 划分为相邻位置的位置去除(这些位置必须要填颜色 \(c\),或者填入这个位置原来的颜色但答案不变,为了方便我们就假定这个位置要填颜色 \(c\)),保留剩下的颜色中出现次数最大的。
等价于:给定一个序列,每次删除若干位置,询问众数的出现次数。由于删除一次带来的出现次数变化不超过 \(1\),所以可以直接指针扫桶维护。
知道出现次数 \(x_{\max}\) 后,答案易知为 \(n - b_c - x_{\max}\)。
时间复杂度为 \(\mathcal{O}(n+m)\)。
Question 3. 「JOISC 2022 Day1」错误拼写
求有多少个长度为 \(N\) 的小写字母字符串 \(S\) 满足如下形式的 \(M\) 个限制:
- 设 \(T_i\) 表示将 \(S\) 中第 \(i\) 个字符删除后前后拼接得到的字符串,则 \(T_{A_j}\) 在字典序上不大于 \(T_{B_j}\)。
答案对 \(10^9+7\) 取余。
\(N,M\leq 5\times 10^5\)
手画一下,这个限制等价于「在区间 \([l,r]\) 中的第一个满足 \(S_k\ne S_{k+1}\) 的位置 \(k\),要满足的是 \(S_k < S_{k+1}\) 还是 \(S_k > S_{k+1}\)」。
举个例子,假设 \(N=3\) 时 \(T_1\leq T_3\),则 \(S_2S_3\leq S_1S_2\),如果 \(S_2\ne S_1\) 则 \(S_1 > S_2\),如果 \(S_2 = S_1\) 则 \(S_2\ge S_3\)。
其中 \(<\) 与 \(>\) 号的选择仅依赖于最初的 \(A_j\) 与 \(B_j\) 的大小关系,从上述可以看出 \(A_j < B_j\) 时取 \(>\)。
考虑 DP,设 \(f_{i,c}\) 表示考虑到前 \(i\) 个位置且位置 \(i\) 填字符 \(c\),初始值可以设 \(f_{1,*} = 1\),答案则取 \(\sum_c f_{n,c}\)。
怎么转移?分情况讨论:
- 如果 \(S_{i-1} = S_i\),则 \(f_{i,c} = f_{i-1,c}\)。
- 如果 \(S_{i-1} < S_i\),考虑枚举上一个 \(j\) 使得 \(S_{j-1}\ne S_j\),则所有 \(l < j\leq r\) 的限制都被位置 \(j\) 满足,所以只需要考虑 \(j\leq l < i\leq r\) 的限制。由于此处钦定了 \(S_{i-1} < S_i\),所以只要找到一个区间 \([l,r]\) 的限制时 \(>\) 就不能转移了,可以发现存在一个点 \(k\) 使得这样的一个区间存在(\(l = k-1\)),故只能从 \(j\in [k,i-1]\) 处转移。假设从位置 \(p\) 转移,则 \(S_p = S_{i-1} < S_i\),同时由于钦定 \(S_{p-1}\ne S_p\),所以将 \(f_{p,c'} - f_{p-1,c'} (c' < c)\) 转移过来。
- 同时由于 \(j\) 的转移是一段区间,所以转移的总值为 \(\sum_{p\in [k,i-1]} f_{p,c'} - f_{p-1,c'} = f_{i-1,c'} - f_{k-1,c'}\)。
- 同理 \(S_{i-1} > S_i\),那么同理只不过是 \(c' > c\)。
总时间复杂度为 \(\mathcal{O}(N\log_2 N + N|\Sigma|)\),本题中字符集大小 \(|\Sigma| = 26\)。
Question 4. 「JOISC 2025 Day2」救护车
现在有 \(N\) 个病人,第 \(i\) 个病人位于 \((X_i,Y_i)\) 处,同时有四家医院分别位于 \((1,1),(1,L),(L,1),(L,L)\),每家医院配有一辆救护车。
救护车按照如下规则运行:
- 救护车每次只能装最多一名病人。
- 救护车接下病人后必须在其所属的医院放下病人。
- 救护车可以花费 \(1\) 个单位时间向边四联通的格子移动,其余行动不耗费时间。
- 多辆救护车的位置可以重合。
请问在 \(T\) 时刻内能否装下将所有病人送到医院?
\(N\leq 160, L\leq 10,000, T\leq 20,000, 1\leq X_i,Y_i\leq L\)
这是在 JOISC 里难得一见的判定性问题,所以我们大胆猜测不是通过算最短时间然后比较的问题。
由于救护车要走一来回,所以不妨直接让 \(T\) 整除 \(2\),随后只需要考虑距离和即可。
如果我们只有 \((1,1)\) 和 \((L,L)\) 两家医院,那么送往两家医院的距离之和相等,可以设一点 \(P\) 的 \(\phi(P) = x(P) + y(P)\),每一次可以让 \(\phi(P)\) 加上 \(1\) 或减去 \(1\),所以距离和为 \(2(L-1)\)。
根据贪心,取 \(X_i + Y_i\) 较小的一段前缀送往 \((1,1)\),其余送往 \((L,L)\) 最优。
感受一下进行类比:现在有四家医院,我们同理可以列出 \(x+y = d\) 与 \(x - y = c\) 两条直线,分全网格图为四个部分,其中对应部分会送往对应边上的两家医院。
- \(x - y\leq c, x+y\leq d\) 的,送往 \((1,1),(1,L)\) 中的一家。
- \(x - y\leq c, x+y > d\) 的,送往 \((L,L),(1,L)\) 中的一家。
- \(x - y > c, x+y\leq d\) 的,送往 \((1,1),(L,1)\) 中的一家。
- \(x - y > c, x+y> d\) 的,送往 \((L,L),(L,1)\) 中的一家。
枚举 \(c,d\),通过选定 \(X_i - Y_i\) 的一段前缀与 \(X_i + Y_i\) 的一段前缀,配合 DP,时间复杂度为 \(\mathcal{O}(N^3T)\)。
具体怎么 DP?设 \(f_{i,j}\) 表示一个区域内送往特定一家医院的时间和为 \(j\),送往另一家医院的时间和最少为多少,类似背包可以直接转移。
检验就枚举某个区域送往某个医院的时间总和,不断推到其余医院(本区域送往另一个医院的时间为 \(t\),另一个区域送往该医院的时间不得超过 \(T - t\)),最终检验一下另一个区域送往该医院的时间总和是否超时即可。
考虑优化,直接顺序扫描 \(X_i + Y_i\),需要考虑的是上述做法的一段前后缀,直接先预先处理好前后缀的背包即可,时间复杂度为 \(\mathcal{O}(N^2T)\)。
Question 5. [CF2152E] Monotone Subsequence
有一个 \((1,2,\cdots, n^2+1)\) 的排列 \(P\),我们得以证明存在一个长度为 \((n+1)\) 的 \(P\) 的单调子序列 \(Q\),通过至多 \(n\) 次如下形式的询问,找出这么一个 \(Q\):
- 给定 \(P\) 的任意一个子序列,交互库返回这个子序列的前缀最大值的下标。
\(n\leq 100\)
首先设 \(A = \{x\mid 1\leq x\leq n^2 + 1\}\),做 \(n\) 次如下操作:
- 在第 \(i\) 次操作中,把 \(A\) 中的下标交给交互库,设交互库返回的下标集合为 \(B_i\)。
- 若 \(|B_i|\ge n+1\),报告 \(B_i\) 中的 \((n+1)\) 个下标(此时为上升子序列);否则将 \(B_i\) 中的元素从 \(A\) 中删去。
如果依旧没有找到答案,那么得以找出一个下降子序列,通过 \(\sum_{1\leq i\leq n} |B_i|\leq n\cdot |B_i|_{\max}\leq n^2\),存在一个没有出现在任何一个 \(B_i\) 中的下标为 \(x\)。
这个下标 \(x\) 肯定是被某个元素遮住了,具体是哪一个呢?考虑在 \(B_n\) 中定位一个最大的 \(y\) 使得 \(y < x\),显然 \(y\) 遮住了 \(x\),但是有没有其它元素遮住 \(x\) 我不知道。
接下来,把 \(x\) 替换成 \(y\),然后在 \(B_{n-1}\) 中继续找,如此依次得到的下标序列描述一个下降子序列(但是此时排列顺序是反的,需要翻转一下)。
为什么这样的寻找能够持续 \(n\) 轮?如果不够了显然该下标出现的 \(B_j\) 中的 \(j\) 应该比实际的 \(i\) 更小。
Question 6. 「USACO 2019 Dec Platinum」Tree Depth
给定一个长度为 \(N\) 的全排列 \(a\),按照如下方式生成一棵二叉搜索树:
generate(l,r):
if l > r, return empty subtree;
x = argmin_{l <= i <= r} a_i; // index of min a_i in {a_l,...,a_r}
return a BST with x as the root,
generate(l,x-1) as the left subtree,
generate(x+1,r) as the right subtree;
设 \(d_i(a)\) 表示以排列 \(a\) 生成的二叉搜索树中节点 \(i\) 的深度(记为该点到根的路径上的点数),设 \(P\) 为长度为 \(N\) 的含 \(K\) 个逆序对的全排列,对所有 \(1\leq i\leq N\) 求 \(\sum_{P} d_i(P)\) 的值,对 \(M\) 取余。
\(N\leq 300, K\leq \dfrac{N(N-1)}{2}\),且 \(M\) 为 \([10^8, 10^9+9]\) 范围的质数。
可以发现这个二叉搜索树中节点 \(i\) 指代的是下标 \(i\),而不是值 \(i\)。
可以通过 DP 求出长度为 \(N\) 的排列中,逆序对为 \(x(x\leq K)\) 的排列个数,依次考虑钦定每个数前面有多少个比它大的数并向后扩展,即记 \(Q(i)\) 为 \(j < i, P_j > P_i\) 的 \(j\) 的数量,显然 \(Q(i) < l\),在末尾加入 \(P_i\) 将新产生 \(Q(i)\) 个逆序对,还可以钦定这个数后面有多少个数比它小,即记 \(R(i)\) 为 \(j > i, P_j < P_i\) 的数量,此时可以向前扩展。
不妨设 \(S(i)\) 表示最终第 \(i\) 次扩展新增的逆序对数量(选择向后取 \(Q(i)\),向前则取 \(R(i)\)),每个逆序对被标记在后插入的数字上,所以计逆序对不重不漏,故 \(\sum S(i) = K\),且 \(S(i)\in [0,i-1]\) 取决于值的排名。
考虑有 \(N\) 组物品,第 \(i(1\leq i\leq N)\) 组物品有 \(i\) 个,体积分别为 \(0,1,\cdots, i-1\),填充一个容量为 \(K\) 的背包,每一组物品选一个,问装满背包的方案数。可以发现这个问题与上述问题等价,所以可以直接用这个问题来描述答案。
我们不好直接通过排列 \(P\) 快速刻画出节点 \(u\) 的深度,考虑用后代关系来刻画,不妨设 \(v\) 是 \(u\) 的祖先。
如果 \(v\) 是 \(u\) 的祖先,那么要求 \(P_v\) 是下标 \(j\in [\min(u,v),\max(u,v)]\) 内的 \(P_j\) 的最小值,钦定后仿佛不能跟逆序对或者先前的 DP 扯上点关系……做不了了?
实则不然,先讨论 \(v < u\) 的情况,此时可以先填下标在 \([v,u]\) 范围内的数,最后填下标在 \([1,v-1]\cup [u+1,N]\) 范围内的数,对 \([v,u]\) 范围内考虑从左往右,假设 \(P_v\) 已经被决定好,接下来插入第 \(i\) 个数 \(P_{v+i}\) 时,因为 \(P_v < P_{v+i}\),只能决定 \(0,1,\cdots, i-1\) 个逆序对,相当于原物品组中的前 \(i\) 组,而后续向后向前扩展则保持第 \(v-u+1\) 至第 \(N\) 组,相当于把第 \(v-u\) 组物品拉出问题的考虑范围。这个最直接的就是视作 OGF 为多个多项式连乘后除去原一个多项式,也可以理解成类似背包问题的计数可以删除,逆做原 DP 得以求出。
那么 \(v > u\) 的情况如何?大多数时候不变,只不过在填入 \(P_v\) 的时候必须强行加入 \(v-u\) 个逆序对,那么强制背包一个容量为 \((v-u)\) 的物品即可,而这个可以看作是下标的移动,等价于把第 \(v-u\) 个物品组删除后填满容量为 \(K - (v-u)\) 的背包。
那么问题就做完了,由于问题仅跟 \(|v-u|\) 有关,先枚举 \(|v-u|\ge 1\) 进行撤销,枚举 \(u\) 统计答案,再加入这个物品。
是不是忘了什么?根的深度为 \(1\),所以每个点的深度都还要 \(+1\),总计要加上符合排列的个数,这个在最初的 DP 中已经求得答案 \(f_K\),所以不要忘记将 \(f_K\) 加入答案中。
时间复杂度为 \(\mathcal{O}(N^3)\)。
Question 7. 「JOISC 2020 Day3」星座 3
给定一张 \(N\times N\) 的照片,其中以左下角为原点构建平面直角坐标系,称第 \(i\) 列为 \(x\in [i-1,i]\) 的格子,第 \(j\) 行为 \(y\in [j-1,j]\) 的格子。
有 \(N\) 座高楼大厦,第 \(i\) 座高楼大厦位于第 \(i\) 列,高度为 \(A_i\),也就是说这一列的前 \(A_i\) 行全部都是高楼大厦的遮挡。
有 \(M\) 颗星星,第 \(i\) 颗星星位于 \((X_i,Y_i)\) 处,即第 \(X_i\) 列第 \(Y_i\) 行,从照片上ps掉它会破坏 \(C_i\) 点和谐度。
称一个矩形区域 \(l\leq x\leq r, d\leq y\leq u\) 是星座,当且仅当:
- 矩形内的任何一个格子都不是高楼大厦的遮挡。
- 矩形内至少两个格子是星星。
星座已经看腻了,为了从照片中ps掉所有可能的星座,求最小总共破坏多少和谐度。
\(N\leq 2\times 10^5\),星星不位于高楼大厦的遮挡,星星不重合。
考虑有一颗高度为 \(h\) 的星星被选中保留下来,那么有哪些星星要被删去?
找到左右的最近的高楼大厦,中间的区域为 \([l,r]\),画一下可以发现只有 \(x\in [l,r], y\ge h\) 要被删去,也就是一个矩形。
看到了 \(h\) 的限制位于 \(y\ge h\),考虑从低到高依次规划星星是否保留。
如果保留,那么原来要求这个位置不能有星星的这些星星,他们一定要被删去。那之后呢?如果上面再有一颗星星,选择把现在这颗删掉,然后再把先前的补回来,怎么办?
反悔贪心!给出一次反悔的机会,设当前的星星价值为 \(c_i\),因为保留之必须删去的星星总价值为 \(S\),显然:
- 如果 \(c_i \leq S\),就直接把 \(c_i\) 删掉,保留之花费更大代价,而且因为其高度更高导致限制的矩形更宽。
- 如果 \(c_i > S\),就暂且把 \(S\) 删掉,但同时给 \(c_i\) 的影响范围一个 \(c_i-S\) 的代价,选中之可以把 \(S\) 留下然后把 \(c_i\) 删掉。
影响范围是一段区间,树状数组即可维护。
时间复杂度为 \(\mathcal{O}(N\log_2 N)\)。
Question 8. 「JOISC 2022 Day1」京都观光
京都可以看作网格城市,东西向路径共 \(H\) 条,从北向南依次编号 \(1\sim H\),南北向路径共 \(W\) 条,从西向东依次编号 \(1\sim W\),设东西向路径 \(i\) 与南北向路径 \(j\) 的路口为 \((i,j)\)。
由于不同的路径带来的效果不同,Kaho-Chan 在不同的路径上走路的时间不同。
- 在东西向路径 \(i\) 上的一个路口向东走一个路口花费 \(A_i\) 的时间。
- 在南北向路径 \(j\) 上的一个路口向南走一个路口花费 \(B_j\) 的时间。
Kaho-Chan 想要从路口 \((1,1)\) 走到路口 \((H,W)\),而且 Kaho-Chan 不喜欢绕路,也就是说她不会向北或向西走,请问最少花费多少时间?
\(H,W\leq 10^5\)
考虑一个非常显然的暴力,设 \(f_{i,j}\) 表示走到路口 \((i,j)\) 的最短时间,则转移考虑两个方向即可,时间复杂度为 \(\mathcal{O}(HW)\)。
但是这个暴力感觉走到头了,而且没有用上一条道路上从一个路口走到下一个路口花费时间相同的形式,考虑从不同的角度入手来看待这个问题。
考虑贪心。不妨仅考虑从路口 \((i,j)\) 走到路口 \((k,l)\),从最基本的两种方式 \((i,j)\to (i,l)\to (k,l), (i,j)\to (k,j)\to (k,l)\) 入手进行比较:
- 前者的代价为 \(A_i(l-j) + B_l(k-i)\),而后者的代价为 \(B_j(k-i) + A_k(l-j)\)。
- 若前者比后者小,当且仅当 \(\dfrac{A_k - A_i}{k-i} > \dfrac{B_l - B_j}{l-j}\)。
- 这个很像斜率式,相当于每次会走斜率小的一方,也相当于不可能走斜率大的地方再转弯。
考虑不断用 set 维护当前的所有相邻道路,每次删去斜率最大的相邻道路的转弯点,正确性感性理解:由于每次删去最大的转弯点,所以当前不可能有比它更大的,但又根据贪心策略不能不删。
使用链表维护下一条路径是哪一条,在后面没有路径的时候累加答案即可。
时间复杂度为 \(\mathcal{O}((H+W)\log_2 (H+W))\)。
Question 9. 「JOISC 2022 Day4」复兴计划
JOI 镇里有 \(N\) 个火车站以及 \(M\) 条因为古旧而废弃的铁路,第 \(i\) 条铁路连接火车站 \(A_i\) 与 \(B_i\) 且宽度是 \(W_i\),保证 \(N\) 个火车站可以通过 \(M\) 条铁路互相到达。
\(Q\) 个铁路公司想要在这里发展,第 \(j\) 个铁路公司的火车只能在宽度是 \(X_j\) 的铁路上行驶。
为了满足铁路公司的要求,你可以花费 \(1\) 的代价使得某一条铁路的宽度 \(+1\) 或者 \(-1\),当然,任意时刻宽度必须为正整数。
请对每个铁路公司回答:如果想让它的火车在铁路上运行,使得可以往返于任意两个火车站,所需要的最小花费是多少?
\(N\leq 500, M\leq 10^5, Q\leq 10^6, W_i, X_j\leq 10^9\),保证 \(X_j\) 升序给出。
这个问题的形式看起来就很像最小生成树,不妨用最小生成树来表述这个问题。
- 给出一个 \(X_j\),每一条边的边权为 \(V_i = |W_i - X_j|\),请问该图的最小生成树边权和为多少?
首先这个绝对值决定了什么?考察 Kruskal 算法,依旧是先把边按照 \(W\) 排序,于是实际上的 \(R_i\) 就变成了单谷的样子,从谷点向连边递增,按照 Kruskal 算法的决策就会先决定谷点然后向两边决策。
但无论如何,按照 \(W\) 排序一定是合理的,这方便我们进行计算。
尝试顺序扫描每一条边,如果它可以使得点对连通,那就连上,否则,如果要将其加入最小生成树,那么一定会切掉 \(A_i\) 与 \(B_i\) 路径上的一条边,那么具体是哪一条?一定会是路径上边权最小的那一条,设它的边权为 \(W_P\),因为此时更大的 \(X\) 一定有 \(X - W_P\) 最大。
那么,「加入当前的 \(W_i\),砍掉之前的 \(W_P\)」这样的一步就可以发现东西了。如果我们认为 \(W_i\) 是更优的,当且仅当 \(X - W_i\leq W_P - X\)(取 \(W_i\) 以下显然更优),解得 \(X\leq \frac{W_i + W_P}{2}\),也就是说,将要删掉的边在生成树内的最大边权就知道了,同理新加入的边在生成树内的最小 \(X\) 也可以计算得到。这里注意一下取整方面的细节。
现在我们得知了每一条边在生成树内的 \(X\) 的区间 \([L_i,R_i]\),且每个 \(X\) 能够生成的边一定构成生成树,于是就需要计算如下问题:
权值线段树大力维护可以计算,但是可以更简单一点,具体的,分别排序 \(L_i,V_i,R_i\),三个指针进行扫描,答案的形式肯定是 \(k\times X + b\) 的形式,扫描的同时维护 \(k,b\) 的值即可。
但是有一个问题:怎么在当前的生成森林中加边、删边、判定连通性,并查集并不能维护删边?再来看一下数据范围,除非你的大脑充斥着 ds,否则你会注意到 \(\mathcal{O}(NM)\) 是个合理的范围,直接暴力 dfs 与维护邻接表即可。
时间复杂度为 \(\mathcal{O}(NM + M\log_2 M + Q)\)。
Question 10. 「IOI2025」节日游戏
Nayra 正在玩一个有关礼券、代币的游戏,每次购买礼券都有可能获得额外的代币,她需要获得尽可能多的礼券,以换取一次去红湖(Laguna Colorada)的旅行。
游戏开始时 Nayra 有 \(A\) 个代币,初始时有 \(N\) 张礼券,第 \(i\) 张礼券的价格是 \(P_i\),类型是正整数 \(T_i\),每张礼券最多购买一次。
假设有 \(X\) 个代币,为了买到第 \(i\) 张礼券,你需要至少 \(P_i\) 元(即要求 \(X\ge P_i\)),然后你的代币数量将变为 \((X - P_i)\cdot T_i\)。
帮助 Nayra 找到合适的购买礼券的顺序并构造之,以使得 Nayra 得到的礼券数量最大化。
\(N\leq 2\times 10^5, A, P_i\leq 10^9, 1\leq T_i\leq 4\)
如果我接下来说到“钱”了,则一定指代代币。
先考察一个子问题:如果 Nayra 可以以某种顺序买到所有的礼券,那么购买的顺序如何?
考虑贪心。假设当前有 \(X\) 个代币,以及两张礼券 \(i,j\),购买两种礼券的顺序为 \(i\to j, j\to i\),其最终代币数量分别为 \(((X-P_i)T_i-P_j)T_j, ((X-P_j)T_j-P_i)T_i\),如果前者较优,也即前者的最终代币数量不小于后者(代币肯定是希望越多越好的),那么解不等式得 \(P_iT_i(T_j-1)\le P_jT_j(T_i-1)\)。每一次可以交换相邻的,直到得到最优解就是按照这个排序。
当然我们需要特殊考虑 \(T_i = 1\) 的礼券,显然这些只能真的把代币花出去,不比那些 \(T_i = 2,3,4\) 的可以赚钱的礼券优秀,所以这些按照价格从小到大放在最后。
按照这样的排序方式,我们可以找到一组解,时间复杂度为 \(\mathcal{O}(N\log_2 N)\),预期通过子任务 \(5\)。
再来考察原问题,还是一样的贪心策略,根据上述证明贪心的最优性从左到右购买,只要不亏钱一定按照贪心后的顺序依次购买,需要亏钱的呢?拿出来依次考虑,那么显然我可以设 \(f_{i,j}\) 表示这些亏钱的礼券的前 \(i\) 张,购买了 \(j\) 张,能够得到的代币数量的最大值。这种 DP 很经典,决策买与不买两种即可。为了输出方案记录转移路径,时间复杂度为 \(\mathcal{O}(N^2)\)。
我还可以证明不亏钱的一定是一段前缀:亏钱则 \((X-P_i)T_i < X\),解得 \(X < \frac{P_iT_i}{T_i-1}\),观察我们贪心的不等式,把 \(i,j\) 分别移到两边有 \(\frac{P_iT_i}{T_i-1} \leq \frac{P_jT_j}{T_j-1}\),如果在某一张礼券时亏钱了,后面的 \(\frac{P_iT_i}{T_i-1}\) 一定更大,则更一定是要亏钱了。
于是直接快速计算不亏钱的礼券买完后剩下多少代币,买完全体礼券的极限代价总和为 \(\sum P_i\leq N\cdot P_{\max}\leq 2\times 10^{14}\),如果代币数量超过这么多则一定能够全部买完。后面的直接 DP。预期通过子任务 \(1,2,4\)。
还缺少一个小小的性质我们就能解决这个问题了!这个 DP 看起来无法优化转移复杂度,也不太像是重设 DP,我们来考察一下 \(j\) 的上限。首先抛开全体 \(T_i = 1\) 的礼券,这些可以到最后枚举亏钱的且 \(T_i > 1\) 的礼券买完后剩下多少钱二分计算最大数量,而这些 \(T_i > 1\) 的礼券,就算第一张亏钱的礼券只亏了 \(1\) 个代币,在后面 \(T_i\) 的乘积不断放大之下,只需要少量礼券就能耗尽所有代币。具体而言,设买亏钱的礼券前有 \(V\) 个代币,则只需要 \(\mathcal{O}(\log_2 V)\) 个礼券就足以耗尽。
于是我们可以直接强制 \(j\leq \mathcal{O}(\log_2 V)\),或者选择手算得到 \(j\leq 50\),所以如果有超过 \(50\) 张亏钱的 \(T_i > 1\) 的礼券时,购买这样的礼券数量不超过 \(50\) 张,于是 DP 状态数量得以优化至 \(\mathcal{O}(\log_2 V)\)。
前面的不亏钱的贪心,中间的亏钱且 \(T_i > 1\) 的 DP,枚举中间部分买的数量,得知剩下的最大钱数,二分最后 \(T_i = 1\) 的最大数量,本问题得以解决。
时间复杂度为 \(\mathcal{O}(N\log_2 N + N\log_2 V)\),二分相比而言很小就省去了。
Question 11. 「Petrozavodsk Summer 2020. Day 1. Warsaw U Contest」K. Even rain
有 \(N\) 根柱子,第 \(i\) 根柱子的高度为 \(h_i\)。降雨后柱子形成的凹槽会有积水,具体的,如果一个点左右均有不比之低的柱子则能积水。
现有恰好将 \(K\) 根柱子高度清零的能力,求使用能力后积水量为偶数的方案数。
答案对 \(P = 10^9 + 7\) 取余。
\(N\leq 25,000, K\leq 25, h_i\leq 10^9\)
设柱子 \(i\) 左边最高的柱子高度为 \(L_i\),右边最高的柱子高度为 \(R_i\),没有则记 \(0\),则积水量为:
\(L_i,R_i\) 可以分别看作是前缀最大值与后缀最大值。
但是,如果 \(K = 0\),那么前缀最大值与后缀最大值就是完全确定的,执行完 \(K\) 次操作后,前缀最大值与后缀最大值只会有 \(\mathcal{O}(K)\) 种可能,极限 \(K+1\) 种。
这启发我们设计 DP,设 \(f_{i,j,p,0/1}\) 表示说当前从前往后考虑到第 \(i\) 根柱子,进行了 \(j\) 次操作,当前前缀最大值是 \(h_p\),当前总积水量的奇偶性的方案数。
对于后缀最大值,同理设计 \(g_{i,j,p,0/1}\) 表示当前从后往前考虑到第 \(i\) 根柱子,进行了 \(j\) 次操作,当前后缀最大值是 \(h_p\),当前总积水量的奇偶性的方案数。
于是我们可以钦定最高柱子进行合并(相同高度时可以钦定靠左的一根),因为最高柱子肯定不会有积水,此时左右两边独立,于是本题便得以解决。
当然合并时最高柱子左右两边比它高的要全部删掉,它本身不能删状态中可以计算出 \(p\) 的值。
时间复杂度为 \(\mathcal{O}(NK^2)\),因为 \(p\) 只有 \(\mathcal{O}(K)\) 种,但是空间复杂度呢?这里就需要一点手法了,不能存储 \(\mathcal{O}(N)\) 个状态。这里给出一种实现方式:计算每个前缀的前缀 \(K+1\) 大值,后缀同理,存储 \(p\) 的时候转为存储它是前缀第几大,空间复杂度为 \(\mathcal{O}(NK^2)\),可以通过。
Question 12. 「UTPC2021」E. Bounding Box
平面上有 \(N\) 个点,点有坐标 \((x_i,y_i)\) 与价值 \(c_i\),从其中选出恰好 \(K\) 个点,最大化:
- 设 \(X_{\max}, X_{\min}, Y_{\max}, Y_{\min}\) 分别表示选出的点的 \(x,y\) 坐标的最值,\(S\) 为选出的点的价值总和。
- 所需最大化的目标式为 \(S + (X_{\max} - X_{\min}) + (Y_{\max} - Y_{\min})\)。
\(K\leq N\leq 2\times 10^5, c_i\leq 10^9\)
换一个说法来描述题目,选择一个点集,然后从其中选择 \(4\) 个点带来 \(+X/-X/+Y/-Y\) 的贡献,然后这个贡献显然是越大越好。
不妨设 \(f_{i,j,s}\) 表示说考虑了前 \(i\) 个点,选择了 \(j\) 个,上述 \(4\) 个坐标贡献已经贡献了哪一些,状压成 \(s\),转移考虑下一个点选择还是不选择,如果选择计算哪些贡献,可以完成 \(\mathcal{O}(nk)\) 的 DP。
但是极限只需要 \(4\) 个点就可以贡献完 \(4\) 个贡献,这也就是说:我们只需要额外的 \(4\) 个点来扩充坐标的极值,其余的可以直接贪心的选择 \(c\) 最大的。
贪心完之后,就有 \(k\gets \min(k,4)\),考虑只有 \(4\) 个点,于是上述 DP 的复杂度变为 \(\mathcal{O}(n)\),但是有一个极限 \(4\times 16\times 16 = 1024\) 的常数,当然可以枚举子集干到 \(324\) 但是既然能过就算了。
Question 13. 「CCPC Online 2025」F. 连线博弈
平面上一圆周上 \(N\) 等分点按照逆时针顺序编号为 \(0,1,\sim, N-1\),现有圆周内 \(M\) 条线段,其端点均为等分点,且 \(M\) 条线段不含公共端点且不退化。
Kaho-Chan 与 Suzune-Chan 将要玩游戏,其中 Kaho-Chan 先手,按照如下规则进行:
- 二人轮流进行操作。
- 每次操作选择两个等分点,满足不存在以两个点中任何一个为端点的线段,且以这两个等分点为端点的一条线段不与操作前的任何一条线段相交。
- 作以这两个等分点为端点的线段。
- 无法操作者失败。
判定 Kaho-Chan 是否具有必胜策略。多测。
\(T\leq 10^5, N\leq 10^9, \sum M\leq 10^5\)
将其视为若干个连通块,每个连通块假设有 \(x\) 个可操作的点,则计算其 \(\text{SG}(x)\) 的值,多个连通块可以用异或进行合并。
现在的问题是求解 \(\text{SG}(x)\) 的值。显然我们可以根据题意进行递推:
- 将一个大小为 \(x\) 的连通块分成大小为 \(y\) 与 \(x-y-2\) 的连通块。
- 不是圆也没关系的,反正它是封闭的。
于是就有:
考虑寻找其规律性,打表发现循环节从第 \(53\) 项开始且长度为 \(L = 34\)。
接下来就是计算每个连通块内部有多少个点,可以用哈希,每次将一条线段的两端(等价于最多 \(3\) 个区间)异或上不同的随机权值,然后权值相同的极大概率就在一个连通块内部。
具体实现可以使用 map,区间异或用差分实现即可,时间复杂度为 \(\mathcal{O}(\sum M\log_2 M + C^2)\),其中 \(C\) 是递推 \(\text{SG}(x)\) 的项数。

浙公网安备 33010602011771号