2025.9 做题记录

CF1310C. Au Pont Rouge *2800

题意

给定一个长度为 \(n\) 的由小写英文字母构成的字符串 \(s\)。对于每种将 \(s\) 分割成连续的 \(m\) 部分的方案,令字典序最小的子串作为元素构成的集合为 \(A\)。将集合 \(A\) 中的元素按字典序逆序排序,求第 \(k\) 个元素是什么。

数据范围:\(2 \leq n, m \leq 10^3; 1 \leq k \leq 10^{18}\)

题解

子串数总和是可以接受的,把所有子串拿出来,排序后二分答案。

之后 DP 统计划分 \(m\) 段,最小字典序大于当前子串的方案有多少个。

直接把所有子串插到 Trie 里面,就能 \(O(1)\) 比较字典序。

每个点往后转移是一段区间,算出区间后直接 DP 即可。

提交记录

CF616F. Expensive Strings *2700

题意

给你 \(n\) 个字符串。每个字符串的成本都是 \(c_i\)。 定义定义域为字符串的函数,其中 \(\operatorname{f}(s) = \sum_{i=1}^{n} c_i \cdot p_{s, i} \cdot |s|\),其中 \(p_{s, i}\)\(s\)\(t_i\) 中出现的次数,\(|s|\) 为字符串 \(s\) 的长度。求对于所有字符串,\(\operatorname{f}(s)\) 的最大值。

注意字符串 \(s\) 不一定是 \(t\) 中的某个字符串。

题解

建出 SA,相当于求一个区间,这个区间的贡献是 \(len\times (\min height)\times \sum c\)

统计每个 \(height\) 作为最小值的答案即可。

特殊处理长度为 \(1\) 的区间。

提交记录

CF1065G. Fibonacci Suffix

题意

我们再次定义斐波那契字符串序列:

$F(0) = $ 0,$F(1) = $ 1,\(F(i) = F(i - 2) + F(i - 1)\),其中加号表示两个字符串的连接。

我们将字符串 \(F(i)\) 的所有后缀按字典序排序后得到的序列记为 \(A(F(i))\)。例如,\(F(4)\) 为 01101,\(A(F(4))\) 为以下序列:01,01101,1,101,1101。该序列中的元素从 \(1\) 开始编号。

你的任务是输出 \(A(F(n))\) 中第 \(k\) 个元素的前 \(m\) 个字符。如果该后缀长度小于 \(m\),则输出整个后缀。

题解

考虑把 \(A(F(n))\) 插入 01 Trie,那么可以算出子树大小后在 Trie 树上走。

现在我们需要算子树大小,假设我们当前走到位置的串是 \(ans\),令 \(f_i\) 表示 \(F(i)\) 中前缀为 \(ans\) 的串的个数,那么子数大小就是 \(f_{n}\)

先把 \(F(14),F(15)\) 暴力算出来,这样可以发现后面的 \(F\) 在前后缀拼接的时候都是 \(F(14),F(15)\) 的某个后缀拼上某个前缀。

\(g_{i,j}\) 表示 \(F(i)\) 拼上 \(F(j)\) 新产生的前缀为 \(ans\) 的串的个数,则 \(f_i=f_{i-1}+f_{i-2}+g_{i-2,i-1}\)

\(g\) 可以由上述性质得到。

提交记录

CF1536F. Omkar and Akmar *2600

题意

Alice 和 Bob 在一个 \(n\) 个格子的环上玩游戏,环上的格子编号为 \(1\sim n\)

每一轮中,玩家可选择一个空格子填入字母 A 或 B,同时要求不能存在两个相邻的格子内的字母相同。若没有合法操作,则游戏结束,当前玩家失败。

假设 Alice 和 Bob 每局游戏两个人都按最优策略行动,问有多少种可能的不同游戏。两种游戏不同,当且仅当回合数不同,或者对于某个回合,放置的字母或单元格编号不同。答案对 \(10^9+7\) 取模。

\(n\leq 10^6\)

题解

核心思想:枚举最后局面,计算每个最后局面对答案的贡献。

首先,两个玩家肯定是能操作就操作,因此最后局面肯定不能继续操作。

那么最后局面一定是一个 ABAB 交替的环上序列,中间穿插若干不相邻的空位。

因为这是环上 ABAB 交替的序列,所以最后填上数的位置个数必定为偶数,因此后手必胜。

当最后局面确定时,两个玩家可以随便操作。因为这相当于有若干个石子,每次操作取走恰好一个石子的简单博弈问题。

假设我们最后确定的局面有 \(i\) 个空格,那么这个局面的操作方案书就是 \((n-i)!\)

我们枚举空格个数,然后计算满足条件的局面个数。再乘上操作方案数。

当空格个数确定时,由于要求空格不能相邻,因此考虑插板,为了方便插板,我们假设环上一开始只有 ABAB...,然后把环从第一次操作的地方断开,对于断开的链,每个位置的后面可以选择放不放空格。

因此,空格个数为 \(i\) 时,总方案数为 \(2\times n\times \binom{n-i}{i}\times (n-i-1)!\)

\(2\) 是因为 AB 可以互换,乘 \(n\) 是因为这是有标号环,需要枚举断开位置的标号。

空格个数一定与 \(n\) 奇偶相同,最后答案为 \(\sum\limits_{i=n\bmod 2}^{\lfloor \frac{n}{2}\rfloor} \left(2\times n\times \binom{n-i}{i}\times (n-i-1)!\right)\)

提交记录

2025/9/7 NOIP 模拟赛 T4 *????

题意

\(n\) 个点的有标号无根树的直径之和。

\(n\leq 500\)

题解

核心思想:以所有直径的交点/边为中心。

\(f_{i,j}\) 表示 \(i\) 个点编号为 \(1\sim i\),深度不超过 \(j\) 的有标号有根树的数量。

\(g_{i,j}\) 表示 \(i\) 个点编号为 \(1\sim i\),深度不超过 \(j\) 的有标号叶向森林(即 \(f\) 去掉根)数量。

如果所有直径交于一边,即直径长度为 \(2k+1\),那么枚举两边点的个数 \(x,n-x\),答案为 \(\sum\limits_{x=1}^{n} (f_{x,k}-f_{x,k-1})\times (f_{n-x,k}-f_{n-x,k-1})\times \binom{n}{x}\div 2\),除以 \(2\) 的原因是交边两侧是无序的。

但是模数不质,且常数不允许我们再存一个 \(2\) 因子,我们不能除以二,考虑强制让 \(1\) 在左侧,即 \(\sum\limits_{x=1}^{n} (f_{x,k}-f_{x,k-1})\times (f_{n-x,k}-f_{n-x,k-1})\times \binom{n-1}{x-1}\)

如果所有直径交于一点,即直径长度为 \(2k\),那么这个点所有子树至少有 \(2\) 个深度等于 \(k\),容斥,答案为 \(n\times \left( g_{n-1,k}-g_{n-1,k-1}-\sum\limits_{x=1}^{n-1} (f_{x,k}-f_{x,k-1})\times g_{n-1-x,k-1}\times \binom{n-1}{x} \right)\)

考虑如何求 \(f\),显然有 \(f_{i,j}=g_{i-1,j-1}\times i\)

考虑如何求 \(g\),有 \(g_{i,j}=\sum\limits_{k=1}^{i} g_{i-k,j}\times f_{k,j}\times \binom{i-1}{k-1}\)

解释一下 \(g\) 的转移,有一个错误的想法是 \(g_{i,j}=\sum\limits_{k=1}^{i} g_{i-k,j}\times f_{k,j}\times \color{red}\binom{i}{k}\),但是这样算,子树是有序的,因此会算重。

考虑把子树按照一定顺序排序,并有序的加入这些子树,由于我们在实时分配编号,因此考虑按子树内的最小值降序排序,然后每次强制让 \(1\) 出现在新的子树里,即 \(g_{i,j}=\sum\limits_{k=1}^{i} g_{i-k,j}\times f_{k,j}\times \binom{i-1}{k-1}\)

初始时 \(f_{0,i}=g_{0,i}=1\)

提交记录

CF1038F. Wrap Around *2900

题意

给定一个字符串 \(s\),字符集为 \(\{0,1\}\)

求有多少长度为 \(n\) 的字符串 \(t\),满足以 \(t\) 为循环节的无限循环字符串包含 \(s\)

\(1\le|s|\le n\le 40\)

题解

\(s\) 在无限循环的 \(t\) 中出现,等价于 \(s\)\(t^2\) 中出现。

考虑建立 KMP 自动机,在自动机上 DP。

但是直接对 \(t^2\) 的结构做 DP 会导致有后效性。

考虑 DP 为什么无法处理 \(t^2\) 的情况,因为正常 KMP 自动机上 DP 只能处理往后加入一个字符,而维护 \(t^2\) 要求我们往中间插入字符。

考虑把 DP 改成只往后加字符的情况。只往后加字符,一种想法是假设 \(t\) 在 KMP 自动机的结束状态确定,然后往后加第二个 \(t\)

时间充裕,因此可以直接枚举 \(t\) 在自动机上最后的节点 \(p\),令 \(f_{i,j,k}\) 表示 \(|t|=i\)\(t\) 在自动机上走到了 \(j\)\(t^2\) 在自动机上走到了 \(k\),初值令 \(f_{0,0,p}=1\) 即可。

时间复杂度 \(O(n^4)\)

提交记录

CF587F. Duff is Mad *3000

题意

给定 \(n\) 个字符串 \(s_1…s_n\)。定义 \(f_y (x)\) 表示 \(s_x\)\(s_y\) 中出现的次数。

\(q\) 次询问,每次给定 \(l,r,k\),求 \(\sum\limits_{i=l}^{r} f_k (i)\)

\(n, q, \sum_{i=1}^n |s_i| \leq 10^5\)

题解

*所有复杂度认为 \(n,q,|s_i|\) 同阶。

搬到 ACAM 上,发现问题可以转化为如下形式:

  • 给定 \(n\) 个点集,保证点集大小之和不超过 \(10^5\),每次询问给定 \(l,r,k\),求编号在 \([l,r]\) 的点中,子树内含有第 \(k\) 个点集中点的个数之和。

直接做很难做,考虑反过来,变成把编号在 \([l,r]\) 的点的子树加一,然后求第 \(k\) 个点集的权值和。

然后如果点集大小为 \(1\),就可以直接做了。

保证点集大小之和不超过 \(10^5\),可以根号分治,点集大小不超过 \(B\) 的直接暴力,复杂度 \(O(nB\log n)\),点集大小大于 \(B\) 的点集不超过 \(\frac{n}{B}\) 个,提前预处理每个点进行子树加对这些点集的贡献,然后维护 \(O(\frac{n}{B})\) 个 BIT 一起扫描线,复杂度 \(O(\frac{n^2}{B})\)

\(nB\log n=\frac{n^2}{B}\),即 \(B=\sqrt{\frac{n}{\log n}}\),此时复杂度为 \(O(n\sqrt{n \log n})\)

但是由于 \(O(\frac{n^2}{B})\) 的空间复杂度无法接受,因此最后决定令 \(B=10^{2.5}=316\),此时当 \(n,q,|s|=100000\) 时,时间复杂度为 \(O(n\sqrt{n}\log n)\)

提交记录

CF1400F. x-prime Substrings *2800

题意

给定一个整数 \(x\) 和一个只包含数字 \(1\)\(9\) 的字符串 \(s\)。设 \(f(l, r)\) 表示子串 \(s[l..r]\) 的数字之和。

我们称子串 \(s[l_1..r_1]\)\(x\)-prime,当且仅当:

  • \(f(l_1, r_1) = x\)
  • 不存在 \(l_2, r_2\) 满足:
    • \(l_1 \le l_2 \le r_2 \le r_1\)
    • \(f(l_2, r_2) \neq x\)
    • \(x\) 能被 \(f(l_2, r_2)\) 整除。

你可以从字符串中删除一些字符。每删除一个字符,字符串会被分成两部分并直接拼接,顺序不变。

请问,最少需要删除多少个字符,才能使字符串中不存在 \(x\)-prime 子串?如果原字符串中本就不存在 \(x\)-prime 子串,则输出 \(0\)

\(1\leq |s|\leq 1000\)\(1\leq x\leq 20\)

题解

考虑要求一些子串不能出现,即多模匹配,搬到 ACAM 上考虑。

\(x\leq 20\),发现 \(x\)-prime 字符串总数不会太多,最多的时候是 \(x=19\),此时所有 \(x\)-prime 字符串建出的 ACAM 大小为 \(4852\)

因此暴力建出 ACAM 后跑 DP 即可,\(dp_{i,j}\) 表示前 \(i\) 个字符走到 ACAM 的 \(j\) 号点最小要删去几个字符,转移显然。

提交记录

CF2045E. Narrower Passageway *2700

题意

有一个 \(2\)\(N\) 列的网格。我们用 \((r, c)\) 表示网格中第 \(r\) 行第 \(c\) 列的格子。每天会安排一个力量值为 \(P_{r, c}\) 的士兵驻守在 \((r, c)\) 位置上。

每列都有 \(50\%\) 的概率被雾气笼罩。定义连通区域 \([u, v]\)\(u \leq v\))为从第 \(u\) 列到第 \(v\) 列连续且无雾的列。

连通区域 \([u, v]\) 的力量可以这样计算。设 \(m_1\)\(m_2\) 分别为该区域内第一行和第二行士兵力量的最大值。具体来说,对于 \(r \in \{1, 2\}\),有 \(m_r = \max (P_{r, u}, P_{r, u + 1}, \dots, P_{r, v})\)。如果 \(m_1 = m_2\),则该区域的力量是 \(0\);否则,力量为 \(\min (m_1, m_2)\)

一个工作日的总力量定义为所有连通区域力量的总和。请计算在任意一天部署的期望总力量。

\(1\leq N\leq 10^5\)

题解

硬讨论也能做,但是有更简单的做法。

变换一下贡献计算形式,对于一个区间,令其贡献为 \(m1+m2-m1[m1=\max(m1,m2)]-m2[m2=\max(m1,m2)]\)

所有区间 \(m1\)\(m2\) 的和都是好求的,\(m1[m1=\max(m1,m2)]\)\(m2[m2=\max(m1,m2)]\) 只需要在单调栈算区间时,规定当前数不小于该区间所对另一行的所有数即可。

提交记录

NOIP 模拟 T3 *????

题意

比较难以描述……

题解

建立笛卡尔树,问题转化为选 \(k\) 个叶子并删除其到根链,最大化删除点权值和。

树形DP,令 \(f_{i,j}\) 表示子树 \(i\) 内选择 \(j\) 个叶子的答案。

\(f_{u,j}=w_u+\max\limits_{0\leq x\leq j} \{f_{ls_u}{x}+f_{rs_u}{j-x}\}\)

不好继续优化,考虑维护 \(f\) 的差分数组,那么贪心地,\(f_u\) 的差分数组就是把 \(f_{ls_u},f_{rs_u}\) 的差分数组从大到小归并,再把第一项加上 \(w_u\)

贪心的正确性在于,总和一定,要让 \(f\) 最优肯定先选择增量大的叶子。

因此每个点维护一个 set 表示这个点 \(f\) 的差分数组,然后启发式合并即可。

提交记录

CF150E. Freezing with Style *3000

题意

给定一颗带边权的树,求一条边数在 \([L,R]\) 之间的路径,并使得路径上边权的中位数最大。输出一条可行路径的两个端点。

\(n\leq 10^5\)

题解

二分答案 \(Mid\),将 \(\geq Mid\) 的边都赋值为 \(1\),其余边赋值为 \(-1\),点分治求最大权值和路径检查其是否 \(\geq 0\) 即可。

点分治中需要使用单调队列代替线段树,并按照子树大小或深度从小到大遍历保证单调队列复杂度,还要进行一些必要的剪枝(找到一条 \(\geq 0\) 的路径后立即退出)。

提交记录

AT_arc072_d [ARC072F] Dam

题意

你负责管理一个最多能储存 \(L\) 升水的水库。一开始,水库是空的。接下来 \(n\) 天,第 \(i\) 天早上,有 \(v\)\(t_i\) ℃ 的水会流进来;每天晚上,你可以决定要放多少水,但你必须保证第二天水不会溢出。水不会蒸发,温度也和流进水之外的因素无关。\(v_1\)\(t_1\) ℃ 的水与 \(v_2\)\(t_2\) ℃ 的水混合后的温度为 \(\dfrac {t_1v_1+t_2v_2}{v_1+v_2}\)。对于第 \(i (i \in [1,n] \cap \mathbb N)\) 天,你需要求出最后水库是满的的情况下能达到的最高水温。不同日期的答案相互独立。

\(1 \le n \le 5 \times 10^5\)

题解

考虑一个贪心,如果 \(i+1\) 时刻加入水的水温比 \(i\) 时刻冷,那么 \(i\) 时刻一定选择不放水,以提高 \(i+1\) 时刻的水温。即使要放水,也是先加入 \(i+1\) 时刻的水,再一起放,这样剩余水温一定不会变差。

那么,我们把所有相邻温度递减的操作合并成一个操作,重复这个过程直到操作满足温度递增。

之后,我们肯定是能放水就放水,但是要保证询问时水池内水的体积等于 \(L\)。手动模拟一下,发现被放掉的水不可能在流回来,流回来也不会更优。因此询问可以等价成:指定体积的滑动窗口,求体积乘以温度的和,单调队列即可。

提交记录

P11283 「GFOI Round 2」Turtle and Nediam

题意

对一个元素互不相同的长度 \(\ge 3\) 的正整数序列 \(a\),定义 \(a\) 的“肿胃数(nediam)”\(f(a)\) 为:

  • \(|a| = 3\) 时,\(f(a)\)\(a\) 的中位数;
  • \(|a| > 3\) 时,取 \(a\) 的任意一个长度为 \(3\) 的子段 \([a_i, a_{i + 1}, a_{i + 2}]\),记这个子段的中位数为 \(x\)\(a\) 删掉 \(x\) 后的序列为 \(b\)\(f(a)\) 为所有 \(b\)\(f(b)\) 的最大值。

乌龟给你一个 \(1 \sim n\) 的排列 \(p_1, p_2, \ldots, p_n\)\(m\) 次询问,每次询问给定 \(l, r\),你需要求出 \([p_l, p_{l + 1}, \ldots, p_r]\) 的“肿胃数(nediam)”,即 \(f([p_l, p_{l + 1}, \ldots, p_r])\)

\(n\leq 10^6\)\(m\leq 5\times 10^6\)

题解

第一反应是找次大值,但这是错的。考虑寻找最大值可能成为答案的区间,因为次大值本质上是原序列某个子区间的最大值。

先找出全局最大值 \(a_x=mx\),显然 \(mx\) 不能成为答案,也不会被删除。并且 \(mx\) 会把数列分为两部分。

\([1,x)\) 为左侧序列,\((x,n]\) 为右侧序列。

只对左侧序列讨论,右侧序列与左侧序列类似。

考虑左侧序列的最大值 \(a_i\) 能否成为答案,为了验证这件事,首先要观察一些删除数的性质:

  • 对于序列的子串 \(a_{l\sim r}\),满足 \(a_p(l\leq p\leq r)\) 是最小值且 \(a_q(l\leq q\leq r)\) 是最大值,那么一定可以把该子序列删到只剩 \(a_p\)\(a_q\)。证明显然。
  • 对于序列的子串 \(a_{l\sim r}\),满足 \(a_p(l\leq p\leq r)\) 是最小值且 \(a_q(l\leq q\leq r)\) 是最大值,如果最后只能保留两个数字,那么这两个数字一定是 \(a_p\)\(a_q\)。证明显然。

为了方便讨论,我们记 \(a_y\)\([1,x)\) 的最小值,\(a_z\)\((x,n]\) 的最小值。

根据性质,为了保留 \(a_i\),我们可以且必须先把序列删到只剩下 \(a_{i/y},a_{y/i},(a_r),a_x,a_z\),因为 \([y,x]\) 最多保留两个,\([x,n]\) 最多保留两个。注意 \(i,y\) 顺序不确定(\(a_r\) 的定义将在 \(y<i\) 的讨论中解释)。

如果 \(y<i\),即 \(a_y,a_i,a_r,a_x,a_z\)\(a_r\) 表示 \([i,x]\) 的最小值,那么如果 \(a_z>a_r\)\(a_i\) 可以成为答案,操作步骤为 \(y,i,r,x,z\to y,i,r,x\to i,r,x 或 y,i,x\)(这里用下标代替值简写);否则为了保留 \(a_i\)\(a_r\) 一定会被删除,\(a_r\) 被删除后无论下一步如何操作都会删掉 \(a_i\)

如果 \(y>i\),即 \(a_i,a_y,a_x,a_z\),删掉 \(a_y,a_x,a_z\) 的中位数即可。

因此 \(a_i\) 能成为答案的充要条件是 \(y>i\)

我们发现 \(y\) 把左侧区间又分为了两部分,我们记 \([1,y)\) 的最大值为 \(a_p\)\((y,x)\) 的最大值为 \(a_q\)

那么 \(a_p\) 一定可以作为答案,当 \(a_q<a_z\)\(a_q\) 也可以成为答案。

特判 \(a_y,a_z\),这两个数的较大值也能成为答案。

右侧是一样的,需要实现的功能是静态 RMQ,使用 ST 表即可。

upd 我们发现刚刚推理有误。Hack 1 4 2 5 6 3,答案为 \(4\)

原因是,\((y,x)\) 中可能存在一个数,满足这个数能作为答案但不是 \((x,y)\) 的最大值。

因此正确做法是找出最靠右的 \(w\),满足 \(a_w<a_z\),然后用 \((y,w)\) 的最大值更新答案。

搞一个单调栈单独维护这个东西。

提交记录

P6913 [ICPC 2015 WF] Tile Cutting

题意

原题面不好描述,这里省掉一步转化。

\(f(x)=|\{(a,b,c,d)|a,b,c,d\in \N\land ad+bc=x\}|\),有 \(n\) 次询问,每次给定 \(l,r\),求 \(\max\limits_{i=l}^{r} f(i)\)

题解

\(d(x)\) 表示 \(x\) 的因数个数。

\[f(n)=\sum\limits_{a+b=n} d(a)\times d(b) \\ =\sum\limits_{a}\sum\limits_{x|(n-a)} d(a) \\ =\sum\limits_{x}\sum\limits_{k} d(n-kx) \]

考虑根号分治,设 \(B=\sqrt n\)

\[f(n)=\sum\limits_{x=1}^{B} \sum\limits_{k} d(n-kx)+\sum\limits_{x=B+1}^{n} \sum\limits_{k=1}^{\frac{n}{x}} d(n-kx) \\ =\sum\limits_{x=1}^{B} \sum\limits_{i=1}^{n} d(i)\times [n\bmod x=i\bmod x]+\sum\limits_{k=1}^{\frac{n}{B}}\sum\limits_{x=B+1}^{\frac{n}{k}} d(n-kx) \]

\(t_{x,y}=\sum\limits_{i=1}^{n} [i\bmod x=y]\times d(i)\ \big(x,y\leq B\big)\)\(g_{n,k}=\sum\limits_{x\geq 0} d(n-kx)\)

\[f_{n}=\sum\limits_{x=1}^{B} t_{x,n\bmod x}+\sum\limits_{k=1}^{\frac{n}{B}} g_{n-(B+1)\times k,k} \\ g_{n,k}=g_{n-k,k}+d(n) \]

\(g\) 需要重复利用以节省空间,注意特殊处理 \(n<B\) 的情况。

我们可以在 \(O(n\sqrt n)\) 的时间复杂度内求出所有 \(f\),之后使用 ST 表查最值即可。

提交记录

CF2013F2 Game in Tree (Hard Version) *3500

题意

Alice 和 Bob 在一棵 \(n\) 个节点的树上玩游戏,规则如下:双方轮流移动,爱丽丝先手。每位玩家在自己的回合中,必须移动到一个未被访问过(无论自己或对手)的相邻节点上。第一个无法移动的玩家输掉游戏。

爱丽丝初始位于 \(1\) 号节点,你需要对于给定简单路径 \(u\to v\)(一定不穿过 \(1\))上的每个节点 \(c\) 判断:若 Bob 初始位于 \(c\),谁将获胜。

玩家的初始位置也被视为访问过的节点。

\(n\leq 2\times 10^5\)

题解

\(dep_{u}\) 表示 \(u\) 的深度,\(dep_{1}=0\)\(length_{u}\) 表示 \(u\) 去掉 \(1\to c\) 的点后子树下的最大深度。

对于点 \(c\),Alice 获胜的充要条件是:

\[\exist u,dep_{c}+\max\limits_{v\in (1\to c)\land dep_{v}>dep_{u}} \{-dep_{v}+length_{v}\}-length_{u}<dep_{u}\leq \lfloor\frac{dep_{c}}{2}\rfloor \]

对于这种复杂的式子,考虑放缩,以缩小 \(u\) 的范围。

对于一个拐点 \(u\),它能使 Alice 获胜的必要条件是 \(dep_{u}+length_{u}-1>dep_{c}-dep_{u}-1\)

\(2\times dep_{u}+length_u>dep_c\)

由于 \(dep_c\) 是常量,\(\sum length_{u}\leq n\),考虑根号分治。

\(length_{u}<B\) 时,\(dep_u\) 的范围极差为 \(O(B)\) 级别。

\(length_u\geq B\) 时,\(u\) 的个数时 \(O(\frac{n}{B})\) 级别。

\(B=\sqrt n\) 即可,时间复杂度 \(O(n\sqrt n)\)

对路径上每个点求 \(length\) 还是有一些细节的。

对 Alice 和 Bob 分别判断,假设在他到达 \(u\) 前,两人都不往下拐,且他在 \(u\) 下拐是否可能赢。称可能赢的点为关于他的必胜点。

取离 Alice 最近的关于 Alice 必胜点和离 Bob 最近的关于 Bob 必胜点,比较一下距离即可。

提交记录

20250921 模拟赛 T1

题意

求长度为 \(n\) 值域为 \([1,m]\) 逆序对个数为偶数的序列个数模非质数 \(mod\) 的值,可以做到 \(O(\log n)\)

题解

打表发现答案为 \(\frac{m^n+m^{\lfloor \frac{n+1}{2}\rfloor}}{2}\)

证明:考虑把 \(12,34,56\dots\) 配对,剩一个不管他,如果存在一个配对中数不相等,那么可以构造奇数逆序对和偶数逆序对序列的映射 \(f:Odd\to Even,交换第一个不相等的配对\)

如果不存在一个配对中数不相等,那么逆序对个数显然为偶数。

因此偶逆序对比奇逆序对序列个数多 \(m^{\lfloor \frac{n+1}{2}\rfloor}\) 个,上述式子正确。

模数不质,因此需要先模 \(2\times mod\) 再除以二。

提交记录

20250921 模拟赛 T2

题意

小 X 和小 Q 在海边捡贝壳。

小 X 把捡到的贝壳分为三类。小 Q 趁小 X 不注意,把贝壳分到了 \(n\) 个袋子里,其中第 \(i\) 个袋子中三类贝壳的数量分别为 \(x_i, y_i, z_i\)

为了安慰小 X,小 Q 让小 X 先选 \(\frac{n}{2} + 1\) 袋贝壳走,剩下的就都归小 Q 了。

小 X 想请你帮助她,找到一种选贝壳的方案,使得她每一类贝壳都不比小 Q 拿到的少。

\(n\leq 10^5\),可以做到 \(O(n)\)

题解

如果 \(n\) 是奇数就补一个 \((0,0,0)\)

\(x\) 排序,选 \(x\) 最大的一个,按 \(y\) 排序,再选剩下的 \(y\) 最大的一个。

然后按 \(x\) 排序后两两配对,\(23,45,67\) 中每组只要选一个就符合条件。

\(y\) 同理,建图,连边表示相邻两个至少选一个。

最终必定形成若干偶环,每个偶环有两个选择方案,选 \(z\) 和大的一个方案即可。

提交记录

20250921 模拟赛 T3

题意

给定 01 矩阵,对每个位置求这个位置翻转后全局的最大全 \(0\) 矩阵。

要求 \(O(nm)\)

题解

对于 \(0\)\(1\) 的情况,相当于要求这个点不选,那么矩形一定在这个点的四个方向外,预处理出上下左右方向的前缀答案即可。

对于 \(1\)\(0\),相当于在普通全 \(0\) 矩阵的问题上新增了一个忽视 \(1\) 的机会,对于每行单调栈维护直方图,每个柱子可以往上长,简单讨论一下即可。

求一个点靠左第二个大于它的值,可以维护链表,从小到大删数,删除前查 \(pre_{pre_i}\) 即可。

提交记录

20250921 模拟赛 T4

题意

给定一个只含字符 xy 且长度为 \(n\) 的字符串 \(S\) 和一个长度为 \(n\) 的数组 \(c_1, c_2, \cdots, c_n\)。你需要进行若干次操作将这个字符串删除。有一个值 \(a\) 初始为 0。

每次操作如下:选中 \(1 \leq i < |S|\) 满足 \(S_i\)x\(S_{i+1}\)y,则将 \(S_i, S_{i+1}\) 同时删除,\(i + 1\) 右侧的字符向前补空位,并给 \(a\) 加上 \(c_i\)

求问所有操作结束后,\(a\) 的最小值是多少呢?如果不能删空 \(S\),输出 No Solution

\(n\leq 5000\)

题解

判无解是简单的。

建立括号树。

\(t_i\) 表示第 \(i\) 个括号被删除的位置。

首先父亲的 \(t\) 必定小于儿子的 \(t\),其次 \(t_i\leq i\),且奇偶性与 \(i\) 相同。

上述性质必要性显然,实际上也具有充分性,证明如下:

我们找到最靠前的一个叶子,它的 \(t\) 必定是它本身的位置,“删”掉它后剩下的 \(t\) 仍然满足这个性质,可归纳证明。这里的“删”指去掉而非题目中的删除。

\(f_{u,i}\) 表示子树 \(u\) 内,\(t_u=i\) 的答案,后缀和优化 DP 即可。

提交记录

CF1916F. Group Division *2900

学习【耳分解与双极定向】。

提交记录

P5776 [SNOI2013] Quare

题意

给定一张图,求一个边权和最小的边双连通生成图(包含所有点,但不一定包含所有边的图)。

输出最小边权和。

\(n\leq 12\)\(m\leq 40\)

题解

根据耳分解,令 \(f_S\) 表示点集 \(S\) 的答案,\(g_{S,i,j}\) 表示 \(S\) 构成耳且以 \(i,j\) 为端点的最小边权和,\(h_{S,i}\) 表示点集 \(S\)\(i\) 连边的最小边权,则:

\[f_{S}=\min\limits_{T\subset S\land i\in S/T\land j\in {S/T}} f_{S/T}+g_{T\cup\{i,j\},i,j} \\ g_{S,i,j}=\min\limits_{k\in S\land k\neq i\land k\neq j}g_{S/\{i\},k,j}+h_{S/\{i\},i} \]

时间复杂度 \(O(n^32^n\times 3^n)\),足以通过这道题。

但是,实际上根本不用这样转移,直接把耳分步转移,令 \(f_{S,i,j,0/1/2}\) 表示当前集合是 \(S\),当前的耳长度 \(=1/>1/=0\),端点分别为 \(i,j\) 的答案,注意特殊处理二元环。当耳长度为 \(0\)\(i,j\) 是没有用处的。

每次转移时往 \(i\) 上加点,或者封闭这个耳。

为了避免重边,单独处理长度为 \(2\) 的开耳和闭耳。

时间复杂度 \(O(n^3 2^n)\)

提交记录

P10809 [LMXOI Round 2] Nirvana

题意

给定一张图,询问有多少组 \(x,y\ (x\leq y)\),满足加入边 \((x,y)\) 后,新图可以定向成一个 DAG,且唯一的零入度点是 \(S\),唯一的零出度点是 \(T\)

若存在这样的 \((x,y)\),选一组 \((x,y)\) 并构造方案。

若不存在,求至少删多少个点使得原图能够定向成一个 DAG,且唯一的零入度点是 \(S\),唯一的零出度点是 \(T\)

\(1\leq n,m\leq 5\times 10^5\)

题解

存在 \(S\to T\) 的双极定向,当且仅当连接 \(S,T\) 后原图点双联通。

连接 \(S,T\),相当于询问有多少种加边方案使得加完边原图是点双。

建出圆方树,连接两个点相当于将路两点径上的所有点缩成一个方点。

点双相当于只有一个双点,容易发现,当且仅当圆方树的方点排成一条链时,才存在这样的加边方案。

此时加边的方案数就是链两端方点的 \(1\) 度儿子个数之积,需要特殊处理只有一个方点(即原图本来就是点双)的情况。

如果 \(P=0\),连接 \(S,T\) 后选出儿子数最大的方点保留即可。

否则,找一组加边方案跑双极定向即可。

注意加入一个自环并不合法,所以计算 \(P\) 时应该去掉这种情况,\(P\) 一定不为 \(1\)

提交记录

QOJ #4805. Grammy Sorting *????

题意

给定一张图和两点 \(A,B\),给定排列 \(p\) 为初始点权。

现在要求你进行操作,使得操作完后对于所有点 \(x\),都存在一条路径,满足:

  • 路径从 \(A\) 开始,经过 \(x\),在 \(B\) 结束
  • 路径从 \(A\)\(B\) 经过的所有点权值递增。

可以进行的操作如下:

  • 选择一条从A开始,任意点结束的路径,假设路径上的点权依次为 \(a_1,a_2,\dots a_k\),将其变为 \(a_2,a_3,\dots a_1\)

操作次数要求 \(\leq 10000\)。(实际 \(1000\) 次就够用了)

\(n\leq 1000,m\leq 2000\)

题解

有解仅当原图存在 \(A\to B\) 的双极定向,并且定向完的 DAG 能被操作成一个满足点权和 bfs 序正相关的 DAG。

先双极定向,然后执行操作。

考虑链的情况,直接模拟插入排序即可,具体地,从后往前维护递增序列,第 \(i\) 次操作保证 \([n-i+1,n]\) 递增。

考虑 DAG,对于一般 DAG 很难做,考虑利用双极定向的性质——bfs 序后缀连通。

我们依然想链一样倒着做,考虑当前操作到了点 \(x\),若 \(p_x< \min\limits_{x\to v} p_v\),直接不进行操作。否则,当 \(p_A< \min\limits_{x\to v} p_v\),把 \(p_A\) 换到 \(p_x\);当 \(p_A> \min\limits_{x\to v} p_v\),考虑将 \(p_x< \min\limits_{x\to v} p_v\) 换到 \(p_x\),具体地,记 \(nxt_i\) 表示 \(i\) 后继中点权最小的,让 \(x\) 不断跳 \(nxt\) 直到 \(p_{nxt_x‘}>p_A\),然后轮换 \(A\to x'\) 即可。

不断跳 \(nxt\) 是因为,这样轮换后,对于每个 \(bfn\) 大于 \(bfn_x\) 的点 \(y\) 依然能够保证 \(p_y< \min\limits_{y\to v} p_v\)

显然这样构造一定有解。

提交记录

CF2151E. Limited Edition Shop *2200

题意

有一家商店,里面有 \(n\) 件从 \(1\)\(n\) 编号的物品,并且每件物品只有一个副本。据你所说,这些物体
具有值 \(v_1,v_2,\dots ,v_n\)(可以为负)。

Alice 和 Bob 对物体有自己的偏好顺序(分别为 \(a_1,a_2,\dots ,a_n\)\(b_1,b_2,\dots,b_n\))。

两人一共进行 \(n\) 次购物,每次其中一人去商店购买店里目前存在的他最喜欢的商品。最后,Alice 和
Bob 有自己的物品集。

在所有 Alice 可能买到的物品集合中,\(v\) 的和最大是多少?

\(n\leq 2\times 10^5\)

题解

这道题的关键是意识到 DP 不可能是一维的,因为在沿着 Alice 顺序转移时,必须记录 Bob 选择到哪了。

\(f_{i,j}\) 表示 Alice 选到了她第 \(i\) 喜欢的物品,Alice 没选的物品中在 Bob 序列最大位置为 \(j\) 的答案,大胆的推一下转移,发现转移都是区间加和单点改为前缀 \(\min\),线段树维护整体 DP 即可。

提交记录

P2934 [USACO09JAN] Safe Travel G

题意

给定一张图,保证 \(1\) 到每个点的最短路径唯一,求对于每个点 \(i\ (2\leq i\leq n)\),去掉 \(1\to i\) 最短路的最后一条边后,\(1\to i\) 的最短路是多少。

\(n\leq 10^5\)\(m\leq 2\times 10^5\)

题解

建出最短路数,点 \(u\) 的答案肯定是向下走到某点 \(v\),找到非树边 \(u\frac{w}{} v\),答案为 \(dis_v-dis_u+w+dis_x\)

启发式合并维护子树内的 \(dis_{x}+w\),每次往上爬一个点就让整个集合加上爬过的边权,维护一个全局懒标记即可。

对于一条非树边,当且仅当一个点在 \(u\) 子树内,另一个点在子树外时可用,因此到达点 \(u\) 时,需要去掉所有 \(\text{lca}\in \text{subtree}(u)\) 的非树边的贡献,用 set<pair<int,int>> 维护集合,第一维记 \(dis_x+w\),第二维记 \(\text{lca}\) 即可。

提交记录

P5100 [JOI 2017 Final] 足球 / Soccer

题意

JOI 联赛足球俱乐部俱乐部有 \(N\) 名球员,编号为 \(1\ldots N\)

足球场可视为一个底为 \(W\) 米,高 \(H\) 米的长方形。

练习结束后,你要回收练习用的足球。开始回收时,所有球员都在足球场上,球员 \(i (1\leqslant i\leqslant N)\) 位于 \((S_i, T_i)\),球在球员 \(1\) 脚下。你正和球员 \(N\) 一起站在 \((S_N, T_N)\),并准备回收球。球员们把球传到 \((S_N, T_N)\) 时,你才会回收球。

你可以指挥球员,但某些操作会提升球员的疲劳度。一个球员不能同时进行多项操作。

你可以指挥控球的球员进行如下操作:

  • 踢球。在东西南北四个方向中任选一个,并指定一个正整数 \(p\),该球员将球朝指定方向踢出恰好 \(p\) 米。假定球滚动时可以穿过其他球员。该球员不会移动,且自动停止控球,疲劳度上升 \(A\times p+B\)
  • 运球。在东西南北四个方向中任选一个,该球员带球,朝指定方向移动 \(1\) 米。该球员仍然控球,疲劳度上升 \(C\)
  • 停止控球。该球员的疲劳度不改变。

你可以指挥没有控球的球员进行如下操作:

  • 移动。在东西南北四个方向中任选一个,该球员朝指定方向移动 \(1\) 米,疲劳度上升 \(C\)
  • 控球。如果该球员所在的位置恰好有球,且没有其他球员控球,该球员才能控球。该球员的疲劳度不改变。

球员和球有可能跑出场外,一个位置上可能有多个球员。

求在回收球的过程中,所有球员上升的疲劳度之和的最小值。

\(1\leqslant H,W\leqslant 500, 0\leqslant A, B, C\leqslant 10^9, 2\leqslant N\leqslant 10^5, 0\leqslant S_i\leqslant H, 0\leqslant T_i\leqslant W(1\leqslant i\leqslant N), (S_1, T_1)\neq(S_N, T_N)\)

题解

因为运球和移动代价一样,所以先把球给出去再接住不如直接带球带过去,所以一定存在最优解使得一个人只控球一次。

然后假设球在一个位置,一定是最近的人移动过去捡球,因为一个人去捡球会损失在原本位置接球的机会,而一个人只会拿球一次,所以实际上什么也没损失。

拆点,令 \(f_{i,j}\) 表示球在 \((i,j)\) 停下的答案,\(g_{i,j}\) 表示球在 \((i,j)\) 被控制的答案,\(p_{i,j}\) 表示球在 \((i,j)\) 横着飞的答案,\(q_{i,j}\) 表示球在 \((i,j)\) 竖着飞的答案,建图跑 dij 即可。

具体地,多元 bfs 求出每个点到最近球员的距离 \(dis_{i,j}\)\(f_{i,j}\)\(g_{i,j}\)\(dis_{i,j}\) 的边;\(g_{i,j}\) 向四连通方向连 \(C\) 的边,向 \(p_{i,j}\)\(q_{i,j}\)\(B\) 的边;\(p_{i,j}\) 向 横向相邻点连 \(A\) 的边;\(q_{i,j}\) 向纵向相邻点连 \(A\) 的边。

不用区分横向的左和右、纵向的上和下,因为允许球掉头一定不会更优。

另外,直接把球员初始位置当成每次球员位置,正确的原因是,可以通过分讨证明,即使球员可以瞬移到初始点也不会更优。

提交记录

P10652 [ROI 2017] 前往大都会 (Day 1)

题意

ROI 国有 \(n\) 个城市,以及 \(m\) 条铁路,每条铁路都是单向运行的,第 \(i\) 条铁路依次经过 \(v_{i,1},v_{i,2},\dots,v_{i,l_i+1}\) 号城市并停靠,其中 \(v_{i,j} \to v_{i,j+1}\) 的铁路长度是 \(t_{i,j}\)

如果多条铁路经过 \(u\) 号城市,那么你可以在 \(u\) 号城市换乘其他铁路。(每条铁路都可以在停靠点任意上车/下车)

你需要找到一条从 \(1\) 号城市到 \(n\) 号城市的路径,这条路径需要满足其总长度最小,并且在此条件上路径上相邻两个换乘点火车上距离的平方和最大。

起点和终点都是换乘点,题目保证有解,\(n,m\leq 10^6\)

题解

先建出最短路 DAG,然后问题相当于在 DAG 上进行上述操作,不需要管路程最短的限制。

考虑一个铁路在 DAG 上肯定是以若干条链的形式出现,这些链相互独立,因此把这些连分割成若干条独立的铁路,下文的所有”铁路“都指分割完之后的铁路。

由于是平方和最大,因此这个问题严格不弱于斜优板子,考虑斜率优化 DP。

具体地,如果存在一条铁路同时经过 \(i,j\),则有 \(f_{j}\leftarrow f_{i}+(dis_j-dis_i)^2\),由于 \(a^2+b^2\leq (a+b)^2\),转移后不换乘一定不优,因此这里并不需要要求 \(j\) 立刻换乘。

我们无法在 DAG 上维护凸包,考虑对每个铁路维护一个凸包,在 DAG 上按拓扑序 DP,每到一个点时遍历经过这个点的所有铁路,求出最大的 \(f\),之后再用 \(f\) 更新所有铁路的凸包即可。

时间复杂度 \(O(n+m\log m)\),瓶颈在于建最短路 DAG。

提交记录

P9734 [JOISC 2021] 逃走経路 (Escape Route) (Day2)

题意

IOI 王国使用 Byou(秒)作为时间单位,将一天划分成 \(S\) Byou,分别称为时刻 \(0,1,\dotsc,S-1\)

IOI 王国中有 \(N\) 个城市和 \(M\) 条双向道路,均从 \(0\) 开始标号。保证任两个城市之间均连通。第 \(i\) 条道路连接城市 \(A_i\)\(B_i\),需要恰好 \(L_i\) Byou 通过。每天的时刻 \(C_i\) 后,第 \(i\) 条道路将开始进行检查,直到当天结束。

JOI 组织是一个活跃在 IOI 王国中的秘密团体。出于其保密性,成员不能在道路上受到检查。如果其成员想要通过道路 \(i\),最晚要在时刻 \(C_i-L_i\) 到达这条路的一端。道路的检查不会影响两端的城市。

现在有 \(Q\) 名 JOI 组织的成员,从 \(0\) 开始标号。第 \(j\) 名成员在某天的时刻 \(T_j\),要从城市 \(U_j\) 出发去城市 \(V_j\)。成员可以在任意城市内停留任意长的时间。注意这名成员可能会在路上花费一天以上。

请计算每名成员花费的最短时间,精确到 Byou.

\(2 \leq N \leq 90\)\(N-1 \leq M \leq \dfrac{N(N-1)}{2}\)\(2 \leq S \leq 10^{15}\)\(1 \leq Q \leq 3 \times 10^6\),图连通。

题解

显然早出发不劣于晚出发,因此对于 \(T=0\) 的询问,直接 dijkstra 即可,但是没啥用。

复杂度 \(Q\) 的系数最多为 \(n\),因此几乎所有东西都要预处理。

对于跨天情况,枚举到哪个城市过第一夜,假设 \(u\) 到城市过夜 \(p\),需要满足 \(u\)\(T\) 时刻出发,能到达,这部分还要预处理,令 \(f_{u,v}\) 表示 \(u\) 出发到达 \(v\) 的最晚出发时间。当然可以二分然后 dij,但是存在更聪明的做法,建出反图后直接 dij 就行了。

有了 \(f\),自然也就能 floyd 预处理出每个点对 \((i,j)\)\(i\) 到达 \(j\) 的最少天数 \(g_{i,j}\)

\(h_{u,v}\) 表示 \(u\)\(0\) 时刻到达 \(v\) 的最短时间,且强行要求不跨天。

\(u\)\(v\) 跨天情况的答案就是 \(\min\limits_{p,q|f_{u,p}\geq T} (S-T+g_{p,q}+h_{q,v})\),把 \(g\)\(h\) 卷起来,枚举 \(p\) 即可。

然后是不跨天。

时间点太多了,考虑对于 \((u,v)\),有用的时间点有多少个?

答案是 \(O(m)\) 个,因为对于一条路,能用的时间段肯定是一段前缀,求出 \((u,v)\) 的最短路,然后等到存在一条边断掉后再在这个时刻跑最短路,以此类推,最多有 \(m\) 条边断掉。

考虑对每个 \((u,v)\) 算出这样的 \(O(m)\) 个路径,单调栈过滤掉无用信息后,询问时直接二分。

具体地,对于每个点 \((u,v)\),模拟上述过程,求最短路,找出第一个不能用的边 \((x,y)\),之后断掉它,再跑最短路。

但是我们有更聪明的实现方式,枚举点对 \((u,v)\) 和边 \((x,y,l)\),计算 \((x,y,l)\) 第一个断掉(非严格)的最短路径长度(不要求其是全局最短路),计算方法为 \(u\)\(f_{u,x}\) 时刻出发到 \(x\) 的时间 \(t_0\) 加上 \(t_0+l\) 时刻从 \(y\) 出发到 \(v\) 的最短路,最短路直接 dij 就行了。这样计算保证经过这条边后这条边立刻断开,因此是正确的。

提交记录

P13065 [GCJ 2020 #2] Emacs++

题意

给定一个长为 \(n\) 的括号串,有一个光标在括号串上,在任何时刻,你可以执行以下三种操作之一来移动光标:

  • 将光标向左移动一个字符。此操作耗时 \(L_i\) 秒。
  • 将光标向右移动一个字符。此操作耗时 \(R_i\) 秒。
  • 将光标传送到与第 \(i\) 个字符的括号匹配的括号处。此操作耗时 \(P_i\) 秒。

\(Q\) 次询问光标在 \(S_i\) 开始到达 \(E_i\) 的最短时间。

数据范围

  • \(1 \leq T \leq 100\),对于最多 9 个测试用例,\(n = 10^5\)\(Q = 10^5\),其他所有情况下,\(2 \leq n \leq 1000\)\(1 \leq Q \leq 1000\)

部分分:

  • 对于所有 \(i\)\(L_i = R_i =P_i = 1\)

题解

史。

如果将匹配的点两两缩成一个点,那么原图是仙人掌图,考虑从这里入手。

对于部分分,直接缩点建立仙人掌,讨论一下环上距离即可。

对于一般情况,由于原图并不是真正的仙人掌,匹配点之间的连边可能同时位于多个环中,因此环上最短路完全可以从一点出环,绕一大圈后回到与之匹配的点,这样当 \(P_i\) 非常大时,可以绕开两点之间权值为 \(P_i\) 的边。

考虑圆方树常用技巧:重标边权,将 \(P_i\) 边重标为两点真实的最短路。

如果我们成功重标边权,我们可以进行类仙人掌最短路状物,唯一和仙人掌最短路不同的是,我们每个匹配点有两个状态,分别为在左侧和在右侧。因此在倍增的时候维护 \(up_{u,j,0/1,0/1}\) 表示 \(u\) 的左/右侧上跳 \(2^j\) 步到 \(2^j\) 级祖先的左/右侧。

太史了,考虑换个实现方式,具体地,我们可以把父亲作为方点,这样契合括号数的结构,更加方便。

实现的时候直接建立括号数就行了。

考虑树形 DP 重标边权。

\(f_{u}\) 表示子树内左侧到右侧的最短路,\(g_{u}\) 表示字数外左侧到右侧的最短路。右侧到左侧同理。

\(f_u\) 自下而上,通过儿子的 \(f\) 转移过来,再和原边权取 \(\min\)

\(g_u\) 自上而下,通过父亲的 \(g\) 和兄弟的 \(f\) 转移,具体地就是在环上绕了一圈。

做完这些后,实现一下环上最短路,处理出 \(up_{*,0,*,*}\),然后倍增即可,这样省掉了 tarjan 建圆方树。

提交记录

[ABC134F] Permutation Oddness

题意

定义 {\(1, 2, \ldots, n\)} 的一个排列 \(p = \{p_1, p_2, \ldots, p_n\}\) 的“奇妙度”为 \(\sum_{i=1}^n |i - p_i|\)

请你求出奇妙度等于 \(k\) 的 {\(1, 2, \ldots, n\)} 的排列的个数,并对 \(10^9+7\) 取模后输出。

\(n\leq 50\)

题解

首先排列的两个经典套路(离散化和顺序填数)似乎都不适用。

其次置换环也不是很适用。

把原问题看成匹配问题,拆贡献,\(\sum\limits_{i=1}^n |i - p_i|=\sum\limits_{i=2}^{n} \sum\limits_{j=1}^{n} [j<i]\times [p_j\geq i]\)

\(f_{i,l,r,x}\) 表示只考虑前 \(i\) 对数,左侧点有 \(l\) 个未匹配,右侧点有 \(r\) 个未匹配,奇妙度为 \(x\) 的方案数。

只考虑前 \(i\) 对数的匹配,必有 \(l=r\),因此状态可以优化成三维 \(f_{i,j,x}\)

转移分为:新加入的点对不匹配、互相匹配、一个匹配前面的点、两个匹配前面的点。

提交记录

AT_joisc2020_q 治療計画 (Treatment Project)

题意

JOI 村庄有 \(N\) 个房屋,这 \(N\) 个房屋里的村民全部感染病毒,有 \(M\) 个治疗方案被提出,第 \(i\) 个治疗方案描述为,在第 \(T_i\) 天的晚上,编号在 \([L_i,R_i]\) 区间内的村民被治愈。

病毒还会继续传播,在某天早上,如果村民 \(i\) 被感染,那么村民 \(i+1\) 和村民 \(i-1\) 也会被感染,因为病毒威力巨大,所以被治愈的村民有可能再次被感染。

选择一些方案使得 JOI 村庄所有村民全部被治愈,一天可以进行很多方案,第 \(i\) 个方案要花费 \(C_i\),求最小花费。

\(1 \le N,T_i,C_i \le 10^9\)\(1 \le M \le 10^5\)\(1 \le L_i \le R_i \le N\)

题解

放到二维平面上考虑。

横轴是村民,纵轴是时间。

一个治疗计划相当于在二维平面上治愈了一个以 \((l,t),(r,t)\) 为底边的直角三角形,最后目的是用这些三角形把平面分割成上下两部分。

我们发现如果按区间右端点排序,把一组正确答案依次加入平面,我们覆盖的区间必定是 \([1,r_i]\)\(r_i\) 是某个治疗计划的右端点。

考虑 DP,令 \(dp_i\) 表示覆盖 \([1,r_i]\) 的最小代价,那么有 \(dp_i+c_j\to dp_j\ (|t_i-t_j|\leq r_i-l_j+1)\),后面的条件是要求两个三角形之间不存在空隙。

直接建图后 dij 跑 DP 的方法极其困难,考虑分析一些性质。

性质一:\(dp_i\) 的最优转移点是所有满足条件的 \(j\) 中,\(dp_j\) 最小的一个。

性质二:如果 \(i\) 能直接转移到 \(j\),就一定不会先转移到别的点再由别的点转移到 \(j\)

因此我们可以维护一个 \(dp\) 值的小根堆,每次使用队首元素把所有能转移到的点转移并入队,根据上述性质,这样被入队的点的 \(dp\) 值之后不会再变得更优。

因此每个点只会入队一次,使用类似势能树的 DS 暴力维护即可。

具体地,按照 \(t\) 排序建立线段树,每个点维护 \(l+t,l-t\) 的最小值,之后每次从线段树上暴力找未入队过的点入队。

上述的性质,本质上说的是只有点权没有边权的最短路可以做到每个点只入队一次,这个性质对一般图也成立。

提交记录

posted @ 2025-09-18 21:48  george0929  阅读(81)  评论(0)    收藏  举报