2025.11.17 - 11.28
Question 1. 「JOISC 2018 Day1」帐篷
一块可以视作 \(H\) 行 \(W\) 列矩阵的露营地,从北到南依次为 \(1\sim H\) 行,从西向东依次为 \(1\sim W\) 列,其中有一些位置有帐篷,每个帐篷的开口可以是东南西北四个方向中的一个,且必须要满足:
- 如果一行存在两个位置有帐篷,则靠西方的帐篷开口朝东,靠东方的帐篷开口朝西。
- 如果一列存在两个位置有帐篷,则靠北方的帐篷开口朝南,靠南方的帐篷开口朝北。
求合法的至少摆放一个帐篷的摆放方案数量,答案对 \(P = 10^9 + 7\) 取余。
\(H,W\leq 3000\)
容易发现一行最多两个,一列最多两个,不然是不可能满足要求的。
考虑如下设计 DP 状态:设 \(f_{i,j}\) 表示在 \(i\) 行 \(j\) 列内摆放帐篷的方案数,接下来我们可以省去一些去重以及一些状态难以优化的计算。
- 如果第 \(i\) 行不摆,则 \(f_{i,j}\gets f_{i-1,j}\)。
- 如果第 \(i\) 行选择一个位置摆,则 \(f_{i,j}\gets 4j\times f_{i-1,j-1}\)。
- 如果第 \(i\) 行选择两个位置摆,则 \(f_{i,j}\gets \binom{j}{2}\times f_{i-1,j-2}\)。
- 如果第 \(i\) 行选择一个位置摆,同时选择前 \(i-1\) 行中的某一行的同一列摆,则 \(f_{i,j}\gets (i-1)j\times f_{i-2,j-1}\)。
则最终答案为 \(f_{H,W} - 1\),要减去什么都不摆的情况,初始值可以取 \(f_{0,*} = f_{*,0} = 1\)。
时间复杂度为 \(\mathcal{O}(HW)\)。
Question 2. 「JOI Open 2021」杂交
现在有一种花的 DNA 序列中仅包含 J、O、I 三种碱基,且长度均为 \(N\),两朵这样的花杂交得到的花的 DNA 序列按照如下方式生成:
- 长度为 \(N\)。
- 设父本与母本的 DNA 序列为 \(A,B\) 而子代的 DNA 序列为 \(C\):
- 当 \(A_i = B_i\) 时,\(C_i\) 与 \(A_i,B_i\) 一致。
- 当 \(A_i\ne B_i\) 时,\(C_i\) 与 \(A_i,B_i\) 均不同。
初始你有三朵花,DNA 序列分别为 \(S_A,S_B,S_C\),你可以任意杂交(包括回交)目前拥有的所有花,求是否能够得到指定的 DNA 序列 \(T\)。
现在给出 \(T\) 上的 \(Q\) 次修改,每次修改将 \(T\) 中下标在 \([L_j,R_j]\) 上的字符改为 \(C_j\),你需要求解修改前与每一次修改后的 \(T\) 是否能够生成。
\(N,Q\leq 2\times 10^5\)
设 J、O、I 分别为 \(0,1,2\),那么 \(A_i,B_i\) 生成 \(C_i\) 在模 \(3\) 意义下就是 \(C_i = - A_i - B_i\)。
那么对于生成的任意 \(S\) 都有 \(S = aS_A + bS_B + cS_C\),由于 \(a,b,c\) 均在模 \(3\) 意义下,所以 \(a,b,c\in \{0,1,2\}\),那么总计不超过 \(27\) 种。
打个表,发现其实只有 \(9\) 种,分别记为 \(S_0,S_1,\cdots, S_8\)。
那么线段树维护,每个节点维护 \(f_{0\sim 8}\) 表示目前的 \(T\) 在其对应区间 \([l,r]\) 上是否与 \(S_{0\sim 8}\) 一致,容易用 \(S\) 上的前缀和进行修改。
时间复杂度为 \(\mathcal{O}(N+Q\log_2 N)\)。
Question 3. 「JOISC 2023 Day3」合唱
合唱团的 \(2N\) 个学生排在一排,从左到右的第 \(i\) 名学生的声部为 \(T_i\),若 \(T_i\) 为 A 则表示唱女低音声部,为 B 则表示唱女高音声部,其中唱女低音声部和女高音声部的学生各 \(N\) 个,没有其余声部。
这些学生需要唱恰好 \(K\) 首歌,每个学生恰好唱其中一首歌,对每首歌都有如下要求:
- 每首歌唱女低音声部与女高音声部的学生数量相同。
- 每首歌唱女低音声部的任意一个学生必须在所有唱女高音声部的学生左边。
当然指挥家意识到这样不一定能达成目标,为此你可以协助指挥家调整队形使得能够达成目标,你能够做的操作如下:
- 交换两位相邻的学生的位置。
求最少需要多少次操作。
\(K\leq N\leq 10^6\)
首先让我们来想个办法来刻画答案,考虑 DP,设 \(f_{i,j}\) 表示安排了 \(i\) 个低音部学生与 \(i\) 个高音部学生唱 \(j\) 首歌的最少操作次数,那么转移就是:
而 \(cost(l,r)\) 就是这一次新增的操作次数,考虑累加前 \(r\) 个 A 和第 \(l\sim r\) 个 B 构成的逆序对数量,把前 \(l-1\) 个 A 还没有计算到的贡献在这里也算一部分。
那么直接大力做,时间复杂度为 \(\mathcal{O}(N^4K)\)。
令 \(P^A_i,P^B_i\) 分别为第 \(i\) 个 A 与 B 的位置,考虑列式 \(cost(l,r) = \sum_{1\leq i\leq r} \sum_{l\leq j\leq r} [P^A_i > P^B_j] = \sum_{l\leq j\leq r} \max(0, r - S_{P^B_j})\),其中 \(S_i\) 表示前 \(i\) 个字符中 A 的数量。
容易知道 \(S_i\) 不降,所以取 \(S_{P^B_j}\leq r\) 的位置是一段前缀,假设是以 \(p_r\) 为结尾的前缀,再令 \(s_i\) 表示 \(S_{P^B_i}\) 关于 \(i\) 的前缀和,那么就有 \(cost(l,r) = r(p - l + 1) - (s_{p} - s_{l-1})\),注意转移的时候取 \(p = \max(l-1,\min(r,p_r))\) 控制边界。此时容易做到 \(\mathcal{O}(N^2K)\)。
根据观察,得以注意到答案关于 \(K\) 具有凸性,那么可以利用 wqs 二分做到 \(\mathcal{O}(N^2\log_2 V)\),令 \(v\) 为 check 的值,于是新的转移式为:
又注意到 \(i\) 关于 \(k\) 是决策单调的,可以二分队列进行决策单调性优化,时间复杂度为 \(\mathcal{O}(N\log_2 N\log_2 V)\),此时可以通过。
当然还可以继续优化,让 \(p_r\) 与 \(r\) 取 \(\min\),把 \(l-1\) 用 \(l\) 替换掉,于是 \(p = \max(l,p_r)\),显然当 \(l > p_r\) 时 \(p = l\),又因为 \(f_i\) 关于 \(i\) 单调不降,所以此时可以只转移 \(f_{i-1}\)(尝试可知甚至不用转移,我同学说这可能是因为这样不优),剩余情况为 \(p = p_r\),带入得 \(cost(l,r) = r(p_r - l) - (s_{p_r} - s_{l}) + v\),发现只有一项 \(l\times r\) 同时与 \(l,r\) 有关,那么可以斜率优化。
此时因为 \(l\leq p_r\),但是 \(p_r\) 关于 \(r\) 单调不降,所以稍微改动一下斜率优化的队尾更新部分即可,时间复杂度为 \(\mathcal{O}(N\log_2 V)\)。
Tips
- 设 \(N\) 个数据的数据组 \(A\),如果 \(A\) 中某个二进制位上一个值 \(v\) 超过一半,则 \(A\) 的绝对众数在该位上的值必定为 \(v\)。
Question 4. 「ROIR 2024 Day2」三元组划分
给定一个长度为 \(n=3k(k\in \mathbb{N}^+)\) 值域为 \([1,m]\) 的正整数序列 \(A\),现在将 \(n\) 个数划分为 \(k\) 个三元组,使得每个三元组都是 \((x,x,x)\) 或者 \((x,x+1,x+2)\) 的形式。
当且仅当 \(k\) 个三元组忽略组内与组间顺序全部相等才认为两种划分方案相同,求划分方案数对 \(P = 10^9 + 7\) 取余。
\(n,m\leq 5000\)
忽略 \((x,x,x)\) 的,也就是我们提前挖走一些 \((x,x+1,x+2)\) 的三元组使得每个数的出现次数都是 \(3\) 的倍数。
先把元素放到桶上进行考虑,考虑 DP,设 \(f_{i,j,k}\) 表示当前考虑到元素 \(i\),其中 \(i-1\) 出现了 \(j\) 次,而 \(i\) 出现了 \(k\) 次,从 \(f_{i-1,j,k}\) 进行转移,现在我们使用一些 \((i-2,i-1,i)\) 的三元组,只要把 \(j\) 干到 \(3\) 的倍数就行。也就是说,假设我们使用 \(t\) 个这样的三元组,那么只要 \(j-t\) 是 \(3\) 的倍数,就可以转移 \(f_{i,k-t,a_i-t}\gets f_{i-1,j,k}\)。
枚举 \(i,j,k,t\),滚掉 \(i\),可以通过 \(n,m\leq 500\) 的分数,这里如果 \(b_i > 0\) 的每个连续段分别考虑并且叠加一些优化(判断 \(f_{i-1,j,k} \ne 0\)),可以直接通过。在这里征集该做法的复杂度上界。
当然可以不枚举 \(j\),只枚举 \(t\),相当于我们要知道 \(j-t(j\ge t)\) 是 \(3\) 的倍数的 \(f_{i-1,j,k}\) 的和,倒序扫描 \(t\),同时用 \(3\) 个桶分别维护 \(j\bmod 3 = 0,1,2\) 的 \(f_{i-1,j,k}\) 的和。
此时就只枚举 \(i,k,t\),可以通过 \(n,m\leq 5000\) 的分数,为什么?
因为总循环次数 \(\sum b_ib_{i+1}\leq \sum b_i^2 \leq (\sum b_i)^2 = n^2\),也就是说时间复杂度为 \(\mathcal{O}(n^2)\)。
Question 5. 「JOI 2013 Final」JOIOI 塔
给定 \(N\) 个扁圆柱形积木,第 \(i\) 块积木的直径是第 \(i\) 小的,写有字符 \(S_i\),一定为 J、O、I 中的一种。
现在需要选出若干个积木组成塔,每个塔中的积木按照直径从小到大排列构成的字符串为 JOI 或者 IOI,则认为这个塔是好的。
每个积木最多出现在一个塔中,求最多能够组成多少个塔。
\(N\leq 10^6\)
不要管我为什么记了这题,反正我想不到有二分。
如果只要求组成 JOI,那么按照直径从大到小直接贪心,能用就用,问题在于 IOI 的塔顶也可以使用字母 I,这会带来很大麻烦。
注意到答案具有单调性,也就是说存在 \(x\) 使得 \(\leq x\) 个塔都能够组成,考虑二分 \(x\),此时我们就强制只会选择 \(x\) 个作为塔底的 I,而这些显然贪心选择最大的。
这也就是说我们对 I 的贪心策略是:如果塔底的数量没有达到 \(x\),则新开一座塔,否则放在塔顶,对 J 和 O 的策略不变。
时间复杂度为 \(\mathcal{O}(N\log_2 N)\)。
Question 6. 「JOI 2017 Final」JOIOI 王国
给定一个 \(N\times M\) 的区块,第 \(i\) 行第 \(j\) 列的区块 \((i,j)\) 的海拔为 \(A_{i,j}\),现在要将这些区块划分为 J 省和 I 省,满足:
- 每个区块恰好属于其中一个省,每个省至少包含一个区块。
- 每个省的所有区块四联通。
- 任意取出一行或一列,其中每个省的所有区块依旧连通。
通过适当的划分,使得两个省内的海拔极差的较大值最小化,求出该最小值。
\(N,M\leq 2000\)
划分合法的条件容易画出是阶梯状,最大值最小化容易想到二分答案,但是我们具体怎么 check 一个答案是否合法?
首先全局最小值 \(H_{\min}\) 与全局最大值 \(H_{\max}\) 划分在一起肯定不优,所以这两个值一定分属两个省,假设我们要检验 \(v\) 的合法性,那么对于一个 \(A_{i,j}\),如果 \(A_{i,j} < H_{\max} - v\) 那就一定只能属于全局最小值所在省;同理 \(A_{i,j} > H_{\min} + v\) 那就一定只能属于全局最大值所在省;如果 \(H_{\max} - v \leq A_{i,j} \leq H_{\min} + v\) 就二者皆可;在上述三种情况之外就无法进行划分了,一定无解。
不失一般性的,设全局最小值所在省占据左上角,在同一行内,找到最右边 \(1\) 类点与最左边 \(2\) 类点,该行的分割线一定在这两个点之间,由于要求分割线随着行增加逐渐左移,对每行贪心选择可以选择的最右侧的分割线一定不劣,那么直接检验即可。
时间复杂度为 \(\mathcal{O}(NM\log_2 V)\),记得做 \(4\) 次旋转,相较每次检验旋转一遍,肯定是一个 \(A\) check 完答案之后旋转 \(A\) 常数更小。
Question 7. 「JOI 2019 Final」独特的城市
给定一棵 \(N\) 个点的树,点的颜色有 \(M\) 种,其中点 \(i\) 的颜色 \(C_i\),称点 \(j\) 对于点 \(i\) 是独特的,当且仅当:
- \(j\ne i\)
- 不存在点 \(k\) 使得 \(k\ne j,k\ne i\) 且点 \(k\) 到点 \(i\) 的距离等于点 \(j\) 到点 \(i\) 的距离。
对树上每个点 \(x\) 求:所有对于点 \(x\) 是独特的点 \(y\) 有多少个不同的颜色?
\(M\leq N\leq 2\times 10^5\)
对于每个点 \(x\),距离它最远的点一定是直径两端点 \(L,R\) 中的一个,两次 dfs 找出 \(L,R\),假设较远的那个为 \(u\),考察 \(u\) 与 \(x\) 之间的路径。
显然 \(u\) 会是叶子,假设 \(v\) 是这条路径上异于点 \(u\) 的点,那么点 \(v\) 的子树(不包含路径上的点的)中最深的那个相对点 \(v\) 的深度为 \(d\),那么以 \(u\) 为根,从 \(v\) 的父亲开始数 \(d\) 个,这 \(d\) 个点就不合法。
于是相当于是:每走一个点,叉掉最后的若干个点,如果 \(M = 1\) 就直接维护深度最小的没有被叉掉的点,判定的时候不要忘记 \(x\) 的子树带来的影响。
当然如果所有点的颜色互不相同,就相当于是(深度)区间维护没有被覆盖的点,覆盖用区间 +1 来刻画,容易做到 \(\mathcal{O}(N\log_2 N)\)。
考虑优化,显然我们要么叉掉最长链,要么叉掉次长链(此时显然遍历进了最长链所在子树),考虑先叉次长链,再叉最长链,于是叉掉的深度是增加的,这样方便维护,可以用栈暴力维护(深度不合法就弹掉,然后加入 \(x\),遍历子树,遍历完成后把 \(x\) 删掉)。由于每个点最多加入其儿子次数次,所以点加入的次数总和是 \(\mathcal{O}(N)\) 的,由此知弹出的次数总和是 \(\mathcal{O}(N)\) 的。
于是总复杂度为 \(\mathcal{O}(N)\)。
Question 8. [CF1870G] MEXanization
对于一个非负整数可重集 \(S\),定义 \(f(S)\) 为:不断选择 \(S\) 的一个非空子集 \(T\) 删除并加入 \(\operatorname{mex}(T)\),直至 \(S\) 的大小变为 \(1\),能够得到的最大值。
给定长度为 \(n\) 的非负整数序列 \(a\),对所有 \(k(1\leq k\leq n)\) 求:初始由 \(a_1,a_2,\cdots, a_k\) 构成的可重集合 \(A\) 的 \(f(A)\) 的值。
\(n,a_i\leq 2\times 10^5\)
首先特判 \(k = 1\) 时的答案为 \(\max(a_1,1)\),以下假定要得到最终集合至少经过一次操作。
能够感受出答案关于 \(k\) 单调不降,因为 \(k\) 可以复刻 \(k-1\) 的操作,只要把 \(a_k\) 先变为 \(0\) 然后与 \(0\) 一起合并就可以复刻,但是加入 \(a_k\) 后会有更大的操作空间。
能够感受出 \(k\) 的答案不会超过 \(k\),最好状况下凑出 \(0\sim k-1\) 各一个。
考虑降序枚举 \(k\) 与答案 \(x\),为了凑出 \(x\) 肯定把 \(\ge x\) 的部分先换成 \(0\),由于与所求问题相关的是数的出现次数,初始需求 \(d\) 为 \(0\sim x-1\) 各一个,按照降序扫描 \(z=x-1,x-2,\cdots,1\),如果 \(z\) 的出现次数 \(b_z\) 不低于 \(d\),则能够留出 \(b_z - d\) 个换成 \(0\);否则对于之后的所有数,需求量 \(d\) 增加 \(d - b_z\)。最后比较 \(b_0\) 与 \(d\) 的大小关系。时间复杂度为 \(\mathcal{O}(n^2)\)。
\(k\) 个数与出现次数,如果 trick 见得多了总会觉得有个根号,考虑哪个部分可能是与根号有关的:如果 \(d\) 增加的部分全部都是 \(b_z = 0\) 就只会有 \(\mathcal{O}(\log_2 k)\) 次,如果 \(d\) 增加的部分全部都是 \(b_z = d - 1\) 就只会有 \(\mathcal{O}(\sqrt{k})\) 次(因为这些 \(b_z\) 的总和为 \(k\)),那么大力用线段树二分查找下一次 \(d\) 增加的位置,可以做到 \(\mathcal{O}(n\sqrt{n}\log_2 n)\),此时可以极限通过(大约 1.6s)。
当然每次都线段树二分太烂了,考虑每一次计算都深搜一次线段树(不要忘记是按照降序的),只要查到当前区间 \(b_z\) 的最小值都不低于 \(d\),那么这里一定不会有 \(d\) 增加的位置,更新 \(0\) 的可用数量直接返回,看起来就是一个可行性剪枝,实测居然通过了!为什么?需要证明时间复杂度。
但是我不会证明时间复杂度,反正是 \(\mathcal{O}(n\sqrt{n})\) 的。
Question 9. [CF1264D] Beautiful Bracket Sequence
定义一个合法括号序列的深度如下:
- 空序列的深度为 \(0\)。
- 若 \(A\) 的深度为 \(d\),则 \(\text{(}A\text{)}\) 的深度为 \(d+1\)。
- 若 \(A,B\) 的深度为 \(d_1,d_2\),则 \(AB\) 的深度为 \(\max(d_1,d_2)\)。
对于任意的括号序列 \(S\),其深度为取其任意合法括号子序列 \(T\) 的深度的最大值。注意:如果 \(S\) 是合法括号序列依旧可以取其任意的子序列算深度。
现在有一个长度为 \(N\) 的括号序列 \(S\),其中有一些字符为 ? 表示可以自由填写为左右括号中的一个,求所有填写得到的字符串的深度的和,答案对 \(P = 998244353\) 取余。
\(N\leq 10^6\)
设 \(p_i,q_i\) 分别为前缀 ( 的数量和 ? 的数量,设 \(r_i,s_i\) 分别为后缀 ? 的数量和 ) 的数量。
考虑将任意的括号序列的深度取其 (...()...) 的子序列形式,并在中心点处进行计算,那么枚举中心点 \(i\),枚举前 \(i\) 个位置中的 ? 有 \(t\) 个变为 (,与之对应的要在后缀填写一些 ? 为 ),为了保证最长,前面 \(i\) 个位置中的 ( 都算在深度当中。
那么可以列式:
朴素的算可以做到 \(\mathcal{O}(N^2)\),利用范德蒙德卷积进行变形:
此时可以做到 \(\mathcal{O}(N)\)。
Question 10. [AGC012F] Prefix Median
给定长度为 \(2N-1\) 的正整数序列 \(A\),将其重排得到 \(A'\),设 \(B_i\) 为 \(A'\) 前 \(2i-1\) 个数的中位数,求得到的序列 \(B\) 的数量。
\(N\leq 50, A_i\leq 2N-1\)
考虑刻画能够得到的序列 \(B\) 的条件,首先先将 \(A\) 排个序,那么肯定有 \(B_n = A_n\)。
如果 \(A'\) 升序排序则 \(B_i = A_i\);如果 \(A'\) 降序排序则 \(B_i = A_{2N-i}\);所以 \(A_i\leq B_i\leq A_{2N-i}\)。
两个两个向 \(A'\) 中加入数值,那么 \(B_i\) 每一步的偏移量最多就是 \(A\) 中的一格(比中位数都大或者都小)。
于是我们得以写出 \(B\) 满足的条件,可以证明这些条件充要:
- \(B_i\in \{x\mid \exists j, A_j = x\}\)
- \(A_i\leq B_i\leq A_{2N-i}\)
- 不存在 \(j < i\) 使得 \(B_i > B_j > B_{i+1}\) 或者 \(B_i < B_j < B_{i+1}\)
考虑对此种情况构造原始序列 \(A\),归纳证明:
- 当 \(i = 1\) 时显然可以构造。
- 当 \(i > 1\) 时,若 \(B_i > B_{i-1}\),则必定取得两个更大的数字,考虑最严格时的情况有 \(B_i = A_{2N-i}\),在前面的构造中,$ > B_i$ 的数字至少有 \(2N - 1 - (2N - i) = i - 1\) 个,而只使用了 \(i - 2 - 1 = i-3\) 个(比 \(B_{i-1}\) 大的只有 \(i - 2\) 个数,而其中必定有 \(B_i\)),所以总存在两个数来选。类似的情况可以类似构造。
前两个条件是容易的,考虑第三个条件,那么我们可以考虑倒着填 \(B\),后面所有的 \((B_i,B_{i+1})\) 都 ban 掉了一些 \(B_j\) 的取值,而每次 \(B_i\) 最多比 \(B_{i+1}\) 多两个候选值 \(A_i\) 和 \(A_{2N-i}\)。
考虑 DP,设 \(f_{i,j,k}\) 表示从后往前考虑到第 \(i\) 个数,其中 \(< B_i\) 的剩下 \(j\) 个候选值,$ > B_i$ 的剩下 \(k\) 个候选值的方案数。
- \(f_{i,j+1,k+1}\gets f_{i+1,j,k}\),表示 \(B_i = B_{i+1}\),新增 \(A_i, A_{2N-i}\)。
- \(f_{i,j',k+2}\gets f_{i+1,j,k}\),表示 \((B_i,B_{i+1})\) 额外把左边的若干个候选值 ban 掉,而 \(+2\) 是新增 \(B_i\) 与 \(A_{2N-i}\)。
- \(f_{i,j+2,k'}\gets f_{i+1,j,k}\),表示 \((B_i,B_{i+1})\) 额外把右边的若干个候选值 ban 掉,而 \(+2\) 是新增 \(B_i\) 与 \(A_i\)。
当然需要注意 \(A\) 中重复元素的处理,可以默认取离 \(n\) 较近的。暴力转移,时间复杂度为 \(\mathcal{O}(N^4)\)。
Question 11. [AGC052C] Nondivisible Prefix Sums
给定日奈子(Hinako)ちゃん最讨厌的素数 \(M\),对于一个正整数序列 \(A\):
- Hinako-Chan 会任意重排 \(A\),想尽一切办法直至 \(A\) 的前缀和中不存在 \(M\) 的倍数。
- Hinako-Chan 会喜欢它当且仅当这样的重排方案存在。
求值域在 \([1,P)\) 中的所有长度为 \(N\) 的正整数序列中有多少个是 Hinako-Chan 喜欢的,答案对 \(P = 998244353\) 取余。
\(N\leq 5000, M\leq 10^8\)
首先显然总和不能是 \(M\) 的倍数。考察如下的贪心算法来交换 \(A\) 中元素使得合法:
- 如果前 \(k\) 项的前缀和为 \(P\) 的倍数,从 \(A_{k+1}\sim A_N\) 中选择一个不为 \(A_k\) 的与 \(A_k\) 交换。
- 那么当且仅当后 \(N-k+1\) 个数全部相同才不合法。
为了使得数字尽量合法,考虑将众数提出,不失一般性设众数为 \(1\),那么一个极限构造是:
- 先追加 \(M-1\) 个 \(1\)。
- 追加一个非 \(1\) 的正整数 \(X\),然后追加 \(M-X\) 个 \(1\)。
- 此时 \(1\) 的数量为 \(S = M - 1 + \sum_{1\leq i\leq K} (M - B_i)\)。
- 所以 \(1\) 的数量过多不合法,可以发现此时 \(1\) 是绝对众数。
设其中有 \(K\) 个数非 \(1\),记为 \(B_1,B_2\cdots, B_K\),那么 \(A\) 中元素总和为 \(\sum_{1\leq i\leq K} B_i + (N - K)\),由于 \(N - K\leq S\) 得元素总和 \(\leq M(K+1) - 1\)。故只要不满足,元素和至少为 \(M(K+1)\),而且不能是 \(M\) 的倍数故至少为 \(M(K+1) + 1\),每一次飞跃 \(M\) 的倍数至少耗费一个不是 \(1\) 的数,至少要飞跃 \(K+1\) 次,但是只有 \(K\) 个,矛盾。
所以这样的构造是充要的,考虑借此来计数。
Case 1. 总和不是 \(M\) 的倍数的数列数量
设 \(f_{i,0/1}\) 表示前 \(i\) 个数的数列总和是否不为 \(M\) 的倍数,则转移:
- \(f_{i,0}\gets f_{i-1,1}\),前 \(i-1\) 项元素和为 \(X\) 时,存在唯一的元素 \(M - X(\ne 0)\) 使得前 \(i\) 项元素和为 \(0\)。
- \(f_{i,1}\gets (M-1)f_{i-1,0} + (M-2)f_{i-1,1}\),前 \(i-1\) 项元素和为 \(0\) 时任意填数前 \(i\) 项和不为 \(0\);前 \(i-1\) 项元素和不为 \(0\) 时要避免 \(M-X\)。
初始值 \(f_{1,1} = M-1\),目标答案 \(f_{N,1}\),本部分做到 \(\mathcal{O}(N)\)。
Case 2. 绝对众数过多的数列数量
设 \(g_{i,j}\) 表示 \(i\) 个非 \(1\) 的正整数带来了 \(j = \sum_{1\leq k\leq i} (P - B_k)\) 个空位的方案数,为了方便计算不合法的情况,那么空位数应当不够,于是 \(j\leq N\)。
考虑第 \(i+1\) 个数填写 \([2,P)\) 中的某个数 \(v\),于是转移为 \(g_{i,j}\gets g_{i-1,j-(P-v)}\),可以前缀和优化做到 \(\mathcal{O}(N^2)\)。
在这个 DP 中,不是 \(1\) 的正整数已经完成了顺序的钦定,所以只需要用组合数取一些位置来放这些正整数即可,于是答案为 \(\sum g_{i,j}\dbinom{N}{i}\)。
注意总消耗 \(U = M - 1 + i + j\) 应当 \(< N\),且元素和 \(S = i - 1 + N - U\) 不能是 \(P\) 的倍数以免算重。当然每个数都可以是绝对众数所以乘上 \(M-1\)。
于是最终时间复杂度为 \(\mathcal{O}(N^2)\)。
Question 12. 「JOISC 2014 Day1」有趣的家庭菜园
给定 \(N\) 株 IOI 草,第 \(i\) 株草的高度是 \(H_i\),JOI 君可以不断执行「交换相邻两株 IOI 草」的操作使得:
- 对于最后排在第 \(i(2\leq i\leq N-1)\) 株的 IOI 草:
- \(\forall 1\leq k < i\),排在第 \(k\) 株 IOI 草的高度不高于第 \(i\) 株,或者
- \(\forall i < k\leq N\),排在第 \(k\) 株 IOI 草的高度不高于第 \(i\) 株。
求最少操作次数。
\(N\leq 3\times 10^5\)
感受一下,可以知道目标状态是单峰的,首先可以想到一个假做法:
- 枚举分界点,求解分界点的逆序对与分界点后的顺序对,求和后求最小值。
为什么错了?对于某些排列,这个分界点不一定存在,但是其中“顺序对与逆序对”的思想可以借鉴。
一株 IOI 草,如果它要挪到前面去,需要的操作次数就是前面比它高的 IOI 草的数量,如果它要挪到后面去,需要的操作次数就是后面比它高的 IOI 草的数量。
那么直接对每一株 IOI 草贪心即可,由于所有的交换次数是在两株 IOI 草种较矮的那一边统计的(高度相同不需要管),所以不会算重。
离散化后树状数组即可,时间复杂度为 \(\mathcal{O}(N\log_2 N)\)。
Question 13. 「JOI 2020 Final」奥运公交
给定一张 \(N\) 个点 \(M\) 条边的有向带权图,边 \(i\) 从 \(U_i\) 连向 \(V_i\),经过代价为 \(C_i\),翻转其方向的代价为 \(D_i\),你可以最多翻转一条边的方向。
你需要最小化 \(1\to N\) 的最短路长度、\(N\to 1\) 的最短路长度、翻转代价的总和,求这个总和的最小值,或者报告无解。
\(N\leq 200, M\leq 5\times 10^4, C_i,D_i\ge 0\)
先提一下本题使用的最短路算法为 \(\mathcal{O}(n^2 + m)\) 的 Dijkstra 算法,以下所有时间复杂度分析基于该算法。
暴力做是容易的,时间复杂度为 \(\mathcal{O}(M(N^2 + M))\)。考虑每条边都出现两次(官方子任务 2),那么翻转一条边相当于多了一条边,考察多一条边对最短路的影响,无非就是经过这条边与不经过这条边,不经过那就保留原来的最短路,经过的话,假设考察的最短路是 \(1\to N\) 而这条边是 \(u\overset{w}{\to} v\),那么最短路的长度就是 \(dis(1,u) + dis(v,n) + w\),其中 \(dis\) 是原图最短路长度。
那么先预处理正反图上 \(1\) 到所有点的最短路与 \(N\) 到所有点的最短路,每条边可以 \(\mathcal{O}(1)\) 计算答案,时间复杂度为 \(\mathcal{O}(N^2 + M)\)。
如果没有每条边都出现两次的限制,但是感受一下,大多数边翻转之后是没有影响的,可以视作是加了一条新边。会造成影响的,一定是 \(1\to N\) 的最短路或者 \(N\to 1\) 的最短路上的边,这样的边只有 \(\mathcal{O}(N)\) 条,每次遇到这样的边就暴力重新算最短路,时间复杂度为 \(\mathcal{O}(N(N^2 + M))\),可以通过。

浙公网安备 33010602011771号