2025.11.3 - 11.15
CSP-S 2025 Summary
这个 sb 除了 A 了 T1 以外一无是处。
这个 sb 在 CSP-S 2025 T2 中用 vector 暴力开出了 \(2^k\) 个大小 \(n + k\) 的并查集成功在最后一档炸飞。
实则只需要每次大力清空即可通过,时间复杂度不变但是常数显著减小,空间复杂度更优。
这个 sb 在 CSP-S 2025 T3 中觉得要用 AC 自动机,但是他忘记了 AC 自动机怎么写(尽管这个 Trick 我猜也想不到)。
这个 sb 永远写不会容斥计数 DP。
Question 1. 「JOI Open 2016」销售基因链
给定 \(N\) 个 RNA 字符串 \(S_i\),即字符集为 ACGU,现给出 \(M\) 个询问,每个询问给出两个 RNA 字符串 \(P_j\) 与 \(Q_j\),求原先的 \(N\) 个字符串中由多少个以 \(P_j\) 为前缀且以 \(Q_j\) 为后缀。
\(N,M,|P_j|,|Q_j|,|S_i|\leq 10^5, \sum |P_j|, \sum |Q_j|, \sum |S_i|\leq 2\times 10^6\)
考虑如下的构造:
- \(S_i'\) 为 \(S_i\)、特殊字符、\(S_i\) 的顺序拼接。
- \(T_j'\) 为 \(Q_j\)、特殊字符、\(P_j\) 的顺序拼接。
于是,\(S_i\) 以 \(P_j\) 为前缀且以 \(Q_j\) 为后缀相当于 \(T_j'\) 为 \(S_i'\) 的子串,具体证明是容易的,考虑对准特殊字符后左右两边匹配的充要条件即可。
问题变为:对每个 \(T_j'\) 询问它是多少个 \(S_i'\) 的子串,考虑将 \(S_i'\) 顺次拼接,相邻两个 \(S_i' , S_{i+1}'\) 中间插入另一种特殊字符,得到文本 \(S^a\),于是相当于询问 \(T_j'\) 在 \(S_a\) 中出现了多少次。
相当于单文本多模匹配,使用 AC 自动机即可通过,时间复杂度 \(\mathcal{O}(L|\Sigma|)\),其中 \(L\) 为总长度而 \(\Sigma\) 为字符集,本题取 \(|\Sigma| = 6\)。
Question 2. [CSP-S 2025] 谐音替换
给出 \(n\) 个字符串二元组 \((s_{i,1}, s_{i,2})\),保证每个二元组内的字符串长度相等,再给出 \(q\) 个询问,每个询问给出两个字符串 \(t_{j,1}, t_{j,2}\),询问存在多少种 \(t_{j,1}\) 的替换法使得得到 \(t_{j,2}\)。
一个字符串 \(S\) 的替换法定义为:
- 将 \(S\) 拆分成 \(x + y + z\) 的形式,其中 \(x,z\) 可以为空。
- 找到一个 \(i\) 使得 \(s_{i,1} = y\)。
- 替换得到 \(S' = x + s_{i,2} + z\)。
称两个替换法不同当且仅当 \((x,z)\) 不同或者 \(i\) 不同。
\(n,q\leq 2\times 10^5, \sum |s_{i,1}| + |s_{i,2}|, \sum |t_{j,1}| + |t_{j,2}|\leq 5\times 10^6, t_{j,1}\ne t_{j,2}\)
首先判掉 \(|t_{j,1}|\ne |t_{j,2}|\) 的情况,然后舍弃 \(s_{i,1} = s_{i,2}\) 的二元组。
类比上一题,考虑上述特殊字符插入的构造形式,进行如下方式的构造:
- 将 \(s_{i,1}, s_{i,2}\) 分别写成 \(ABC,ADC\) 的形式,令 \(s'_i\) 为 \(A\)、特殊字符、\(BD\)、特殊字符、\(C\) 的顺次拼接。
- 将 \(t_{j,1}, t_{j,2}\) 分别写成 \(ABC,ADC\) 的形式,令 \(t'_j\) 为 \(A\)、特殊字符、\(BD\)、特殊字符、\(C\) 的顺次拼接。
- 其中 \(A,C\) 分别为最长公共前后缀。
我们声明:如果 \(t_{j,1}\) 能够通过二元组 \((s_{i,1}, s_{i,2})\) 替换得到 \(t_{j,2}\),当且仅当 \(s_i'\) 是 \(t_j'\) 的子串。
考虑将两个特殊字符对齐,\(D\) 不匹配则无法得到 \(t_{j,2}\),而 \(ABC\) 不匹配则无法进行替换。
于是就相当于:给出 \(n\) 个模式串,再给出 \(q\) 个询问,每个询问给出一个文本串,求有多少个模式串是该文本串的子串。容易用 AC 自动机解决。
时间复杂度 \(\mathcal{O}(L|\Sigma|)\),其中 \(L\) 为总长度而 \(\Sigma\) 为字符集,本题取 \(|\Sigma| = 27\)。
Question 3. [CSP-S 2025] 员工招聘
接下来的 \(n\) 天进行 \(n\) 场面试,编号为 \(1\sim n\) 的 \(n\) 个人参加面试,每天面试其中一个人。
每天的面试的题目难度 \(s_i\in \{0,1\}\),当 \(s_i = 0\) 时所有人都平等的不会,\(s_i = 1\) 时所有人都平等的会,一个人能够留下当且仅当 TA 会当天的题目。
每个人都有耐心,具体的,第 \(i\) 个人的耐心是 \(c_i\),在第 \(i\) 个人参加面试前有至少 \(c_i\) 个人没有被留下或者自愿放弃时,第 \(i\) 个人将自愿放弃。
请问留下至少 \(m\) 个人,面试的顺序有多少种?答案对 \(P = 998244353\) 取余。
\(m\leq n\leq 500\)
著名人士曾说过:“如果是外向树简单树形背包即可,容斥一下就变成外向树了”。考虑沿用这个做法,首先找到这个“外向树”的情形。
考虑 \(m = 1\),只要我能搞定一个人就可以了,不妨容斥计算一个人都留不住的情况。
对于第 \(i\) 个参加面试且不会被题目淘汰的人,假设其前面有 \(w_i\) 个 \(s_j = 0\) 的位置 \(j\),又假设其前面有 \(t_i\) 个 \(s_j = 1\) 的人放弃了,那么这个参加面试的人只要 \(c_i\leq w_i + t_i\) 就会放弃。由于此时所有人都会放弃,取 \(t_j = i-1\) 合理。
也就是说,当按照面试顺序的所有 \(s_i = 1\) 的位置 \(c_i\) 都有 \(c_i\leq w_i + i-1\),则这个状态就会一个人都留不住。
考虑计数,按照限制从小到大的顺序填写每一个 \(s_i = 1\) 的位置 \(c_i\),此时大限制一定在后面考虑,前面所有填写的数字都无一例外落在这个限制区间内,类比:
- 给定长度为 \(N\) 的正整数序列 \(A_i\),求有多少个 \(N\) 的全排列 \(P\) 满足 \(1\leq P_i\leq A_i\)。
设 \(c\) 的桶的前缀和为 \(S\),列式可知答案为 \(T = \overset{L}{\underset{i=1}{\prod}} [S_{w_i + i - 1} -(i-1)]\),于是最终结果为 \(n! -(n-L)!\times T\),其中 \(L\) 为 \(s_i = 1\) 的位置个数,可以在 \(\mathcal{O}(n)\) 复杂度内解决。
“外向树”就做完了,考虑对任意情况容斥成“外向树”。由于某些人不一定会放弃,即 \(c_i > w_i + t_i\),此时就构成了反向的偏序关系,不好解决。容斥成全体减去 \(c_i\leq w_i + t_i\),直接强制选定其中 \(u\) 个人在不放弃的时候计算 \(c_i\leq w_i + t_i\),其余的 \(L-u\) 个人计算没有限制的情况,容斥系数为 \((-1)^t\)。
考虑 DP,设 \(f_{i,x,y}\) 表示所有不会因为题目淘汰的位置中考虑了前 \(i\) 个,有 \(x\) 个被选定为离开,剩余 \(i-x\) 个中有 \(y\) 个不合法,转移考虑第 \(i+1\) 个人:
- 第 \(i+1\) 个人离开,根据 \(T\) 的式子,转移为 \(f_{i,x,y}\times \max(S_{w_{i+1} + x} - (x+y),0)\to f_{i+1,x+1,y}\),因为额外的 \(y\) 个人会占位置但是不能提供真正放弃的人(这是为了不影响最终对后续放弃的人的计算),也就是无法提高上限 \(t_j\) 但是额外 ban 掉了一些人。
- 第 \(i+1\) 个人不离开,但是钦定不合法,转移为 \(f_{i,x,y}\times \max(S_{w_{i+1} + x} - (x+y),0)\to f_{i+1,x,y+1}\)。
- 第 \(i+1\) 个人不离开,钦定计算任意情况,转移为 \(f_{i,x,y}\to f_{i+1,x,y}\)。
钦定为任意状态的人,与所有填入 \(s_i = 0\) 的位置的人一同可以任意乱排,于是最终答案为 \(\underset{x+y\leq n}{\sum} (-1)^yf_{L,x,y}(n-x-y)!\),时间复杂度为 \(\mathcal{O}(n^3)\)。
Question 4. 「JOISC 2018 Day2」最差记者 3
\(N\) 个人与一名旗手排成一队进入会场,会场可以看成数轴,时刻 \(0\) 结束时旗手(\(0\) 号)位于位置 \(0\),第 \(i\) 个人的位置为 \(-i\)。
旗手的速度为正方向每时刻 \(1\) 单位长度,第 \(i\) 个人有一个缓慢度 \(D_i\),表示第 \(i\) 个人只会在当 TA 与第 \(i-1\) 个人的距离超过 \(D_i\) 时才向前走,并且一直走到前一个人后面一单位长度的位置。
每个时刻,旗手先走,然后编号为 \(1,2,\cdots,N\) 的人依次根据 \(D_i\) 来决定是否向前。
作为记者的你在睡大觉导致没有拍到照,所以你打算根据一些信息在背景照片上画出人的位置,给出 \(Q\) 个询问,你想知道时刻 \(T_j\) 结束的那一刻位置 \([L_j,R_j]\) 中的人的数量。
\(N,Q\leq 5\times 10^5, D_i,T_j\leq 10^9, 1\leq L_j\leq R_j\leq 10^9\)
走走停停非常难受,考虑对于每个人刻画 \(p_i,w_i\),表示第 \(i\) 个人每 \(p_i\) 个时刻向前走 \(w_i\) 的单位长度。
显然 \(p_0 = w_0 = 1\),用 \(p_i,w_i\) 来计算 \(p_{i+1},w_{i+1}\),显然要达到 \(D_{i+1}\) 才会使得第 \(i+1\) 个人向前,于是 \(p_{i+1} = \lceil{\frac{D_{i+1}}{w_i}}\rceil\times p_i, w_{i+1} = \frac{p_{i+1}}{p_i} \times w_i\)。根据这个式子我们可以发现几个性质:
- 如果 \(p_i\) 转移 \(p_{i+1}\) 发生变化,则 \(p_{i+1}\ge 2p_i\)。
- 如果 \(p_i = p_{i+1}\),那么 \(w_i = w_{i+1}\)。
所以相同 \(p\) 的连续段只需要考虑 \(\mathcal{O}(\log_2 T_{\max})\) 个,且每个连续段的 \(p,w\) 都是固定的,那么目标 \([L_j,R_j]\) 的位置等价于初始时要落在一段区间内,用这段区间与实际这一部分人所在的区间求交集大小后累加即可。
时间复杂度为 \(\mathcal{O}(N+Q\log_2 T_{\max})\)。归纳法可以证明 \(p_i = w_i\) 恒成立。
Question 5. 「JOISC 2019 Day4」合并
JOI 合众国的 \(N\) 个城市通过 \(N-1\) 条道路连接成树形结构,\(N\) 个城市分属 \(K\) 个州,第 \(i\) 个城市属于第 \(S_i\) 个州,每个州至少管辖一个城市。
我们称 JOI 合众国是「可南北独立的」当且仅当存在两个非空的城市集合 N 与 S 使得如下条件成立:
- 每个城市属于 N 组或 S 组中的恰好一组。
- 每个州的所有城市属于同一组。
- 每个组的城市不需要经过另一个组的城市就可以互相到达。
为了使得 JOI 合众国不是「可南北独立的」,K 总统可以不断执行如下操作:
- 选择两个州将其合并为一个,这个新的州管辖原来两个州的所有城市。
请问达成目标的最少操作次数是多少?
\(K\leq N\leq 5\times 10^5\)
一个状态时「可南北独立的」,相当于可以断掉一条边,使得每一个组只恰好落在其中一侧。
考虑 \(K = N\) 时,也就是要把一棵树缩成一个连通块,比较贪心的想法就是每次选择两个叶子,然后把这两个叶子所在州合并,这就等价于把一条路径缩成一个州。
设叶子节点的数量为 \(L\),那么就需要 \(\lceil{\frac{L}{2}}\rceil\) 次操作,适当的选择叶子的组合可以达成目标,感受一下这个就是最优解。
接下来考虑任意情况,如果两个州互相交叠那么就同属一个连通块,我们先合并这些交叠的州,具体怎么做?
- 将一个州下辖的 \(M\) 个城市两两之间的路径进行合并,根据连通性显然只需要考虑 \(M-1\) 对点对就能合并完全。
- 可以用并查集进行维护。总合并次数为 \(\mathcal{O}(N)\) 的。
合并完之后,将留下的边与连通块重新建树,就回到了 \(K = N\) 的情况了。时间复杂度为 \(\mathcal{O}(N\alpha(N))\)。
Question 6. 「JOISC 2016 Day3」电报
给定一个 \(N\) 个点的图,每个点的出度均为 \(1\),初始时第 \(i\) 个点连出的边指向点 \(A_i\)。
每次可以花费 \(C_i\) 的代价改变第 \(i\) 个点的出边连接的点,请问使得图强连通的最小代价是多少?
\(N\leq 10^5, A_i\ne i\)
图为内向基环树,所以强连通当且仅当这个图是一个大环。
首先,改变代价的最小化等价于不变的代价的最大化,接下来考虑如何最大化。
手动模拟一个小样例,初始时的一些边能够被保留,当且仅当以下两个条件成立:
- 每个点的入度不超过 \(1\)。
- 没有组成大小不为 \(N\) 的环。
注意第 \(2\) 条,因为可能初始情况已经满足了。
于是可以贪心,首先对每个点贪心选出代价最大的入边,这样只可能违反第 \(2\) 条,也就是会组成小环,对每一个小环分别考虑做一次调整:
- 选定环中一个点,断掉这个点的入边,如果这个点还有其它的入边,选出剩下的中代价最大的入边保留。
感受一下这样不会造成一个新的小环。
时间复杂度为 \(\mathcal{O}(N\log_2 N)\),排序改成大力查找应该可以做到 \(\mathcal{O}(N)\)。
Question 7. 「JOISC 2024 Day1」鱼 3
给定 \(N\) 条鱼,第 \(i\) 条鱼希望恰好达到 \(C_i\) 的智力,每条鱼的初始智力为 \(0\),现在有两种饲料:
- 饲料 A 的效果:使得某条鱼 \(k\) 的智力增加给定常数 \(D\)。
- 饲料 B 的效果:使得编号 \(\ge k\) 的鱼的智力均增加 \(1\)。
现在有 \(Q\) 个询问,每个询问给出区间 \([L_j,R_j]\),请问如果每份饲料的 \(k\) 都可以自由选定,是否能够使得编号在区间内的鱼均达到智力预期?如果可以,请额外求出最少喂养多少份饲料 A。
\(N,Q\leq 3\times 10^5, C_i,D\leq 10^{12}\)
首先每条鱼的预期智力都不一样,这太难以考虑了,考虑反向整个过程,即从每条鱼的智力均为 \(C_i\) 反推到全部为 \(0\),于是问题就得以简化。
如果一份饲料 A 都不加,仅通过饲料 B 来达成全部清零,肯定需要 \(C_i\) 单调不减,但是这不一定成立,所以可以用饲料 A 来进行单点修改使得其单调不减,由于只能向下减,所以从后往前贪心,每次将 \(C_i\) 减到不大于 \(C_{i+1}\),同时让 \(C_i\) 尽量大,为 \(C_{i-1}\) 留操作空间的同时能够使得饲料 A 的最少化,如果不得不使得 \(C_i < 0\) 则无解。暴力维护之时间复杂度为 \(\mathcal{O}(NQ)\)。
考虑 \(D = 1\),此时控制可以非常精细,所以肯定是有解的。怎么样来刻画这个条件呢?每个 \(C_i\) 肯定要减到 \([C_i,C_{R_j}]\) 的最小值,等价于子序列的后缀最小值。在单调栈上,等价于从左往右来维护一个栈顶到栈底单调减的单调栈,一个位置 \(p\) 被栈中最小的 \(q (p\leq q)\) 覆盖,那么 \(C_p\) 就要减到 \(C_q\)。
离线询问,询问挂到 \(R_j\) 上,单调栈扫描线,同时维护一个栈底到栈顶的前缀和(值乘上大小),这样就不需要用数据结构维护了,每次二分 \(L_j\) 在栈中哪个位置即可。总和减去每个位置被覆盖的元素和,时间复杂度为 \(\mathcal{O}(Q\log_2 N)\)。
对于 \(D\ne 1\) 时考虑将其归约到 \(D=1\) 的情况,先考虑特殊性质 \(C_i\ge C_{i+1}\),给出一个例子 \(\{16,14,13,8,6,5\}\),凭感觉来写一下可以怎么样规约,设 \(C\) 等价于在 \(D=1\) 时的序列 \(B\):
- \(B_6 = 1\),因为它最多减一次。
- \(B_5 = 2\),因为它至少要减到比 \(B_6\) 小。当 \(B_6 = 1\) 时 \(B_5\) 减一次(即 \(C_5 = 3, C_6 = 5\)),当 \(B_6 = 0\) 时 \(B_5\) 减两次(即 \(C_5 = 0, C_6 = 2\))。
- \(B_4 = 3\),同理类比可得。
感受一下,当 \(C_i\ge C_{i+1}\) 时,则有 \(B_i = B_{i+1} + \Big\lceil{\frac{C_i - C_{i+1}}{D}}\Big\rceil\)。发现除去无解可以通过,考虑怎样判定无解。显然如果 \(B_i = x\) 要减到 \(B_i = y\),而 \(C_i < (x-y)D\) 就无解。根据 \(B\) 这样的生成规则,如果对于某个 \(R_j\) 从位置 \(p\) 开始无解,那么对于 \(L_j(L_j\leq p)\) 肯定无解,所以只需要判定对于 \(B_{L_j}\) 是否会减到负数即可。
最后,同理模拟一下 \(C_i < C_{i+1}\) 时,为了方便(最小值不一定在最后)设 \(C_{n+1} = 0\),则有 \(B_i = B_{i+1} - \Big\lfloor{\frac{C_{i+1} - C_i}{D}}\Big\rfloor\)。
于是问题就做完了,时间复杂度为 \(\mathcal{O}(Q\log_2 N)\),单调栈即可完成。
Question 8. 「JOISC 2022 Day4」一流团子师傅
有 \(N\) 种不同的团子,每种团子各 \(M\) 个,共计 \(N\times M\) 个,现在想要制作 \(M\) 个不同的团子串,每串上 \(N\) 种团子各一个。
现在有一个分拣器,往分拣器里输入一些团子的编号,可以知道这些团子能够组成最多多少串团子,当然,这里的一串必须满足每串上 \(N\) 种团子各一个。
请在使用不超过 \(50,000\) 次分拣器,确定每一串团子使用的团子的编号。
\(N\leq 400, M\leq 25\)
Solution 1
考虑一个暴力,每次从当前的团子的集合里面执行如下操作:
- 先取出其中一个。
- 随后判断剩余的团子,如果取出后数量继续 \(-1\) 就说明这一串已经有了这种,放回;否则这一串一定没有这种,取出。
随机化一下即可,期望极限 \(\mathcal{O}(NM\ln M)\)。
Solution 2
考虑一个暴力,每次考虑将这个团子插到哪一串上,从 \(1\sim M\) 枚举每一串,如果这个团子插到第 \(k\) 串不影响后面 \(M-k\) 串可以串完(把剩下的团子与后 \(M-k\) 串已经确定的拿出来查询一遍数量),那么就插入第 \(k\) 串。
根据「JOISC 2015 Day4」遗产继承的 Trick,将枚举改为二分即可。
查询量级为 \(\mathcal{O}(NM\log_2 M)\)。
时间复杂度为 \(\mathcal{O}((NM)^2)\)。
Question 9. 「JOISC 2014 Day3」稻草人
荒地上有 \(N\) 座神社,第 \(i\) 座神社位于 \((X_i,Y_i)\) 处,神谕降下,你需要找到一块地用来建设烟堆,满足:
- 烟堆是一个各边平行坐标轴的矩形。
- 烟堆的左下角和右上角分别有神社,除此之外矩形内的任何位置(包括内部与边界)不存在任何神社。
求可以建设烟堆的位置数量。
\(N\leq 2\times 10^5\),且 \(X_i\) 互不相同,\(Y_i\) 互不相同。
容易做到 \(\mathcal{O}(N^3)\),考虑如何进行 \(\mathcal{O}(N^2)\) 暴力:
首先按照 \(X_i\) 排序,然后枚举左下角的神社,确定左下角的神社 \(p\) 后枚举从左往右枚举神社 \(q(q > p)\),如果 \(Y_q\) 是 \(p+1\sim q\) 的 \(Y\) 的最小值且大于 \(Y_p\) 就可行,否则不可行。
优化可以采用线段树大力维护,但这里讲述分治做法:
将点分为左半边与右半边,考虑跨过中线的点对能够贡献的答案,不妨设当前区间为 \([l,r]\) 而中点为 \(M\),对于左半边的某个点 \(p\),如果右半边的一个点 \(q\) 能够贡献,\(Y_q\) 一定比 \(Y_{p+1}\sim Y_M\) 都要小,也就是说,假设 \(p < r\leq M\) 且 \(Y_r > Y_p\),那么 \(Y_r\) 就限制了 \(Y_q\) 的上界,记为 \(U_p\)。
同理对于右半边的点 \(q\),假设 \(M < s < q\) 且 \(Y_s < Y_q\),它会限制点 \(p\) 的 \(Y_p\) 下界,记为 \(D_q\)。
那么,一个 \(p\leq M < q\) 可以产生贡献当且仅当 \(D_q\leq Y_p\leq Y_q\leq U_p\),也就是 \(L_q\leq L_p\leq R_q\leq R_p\),扫描线的同时先按照 \(R_p,R_q\) 升序,那么可以按照如下方式完成计数:
- 计算 \(L_q\leq L_p, R_q\leq R_p\) 的数量。
- 然后减去 \(R_q < L_p\) 的数量。
于是二维数点即可,注意这是分治里面不要写假,时间复杂度为 \(\mathcal{O}(N\log_2^2 N )\)。
Question 10. [Petrozavodsk Summer 2024. Day 4] C. Modulo 4
设 \(A\) 为所有由 \(0\) 或 \(1\) 或 | 构成,且开头与每个 | 之后都有一个 \(1\) 的字符串构成的集合。
设 \(B_n\) 为所有满足 \(S\in A\) 且将 \(A\) 视作表达式(| 为按位或,每一个极长数字连续段视作一个二进制数)后结果为 \(2^n - 1\) 构成的集合。
设 \(C_n\) 为所有满足 \(S\in A\) 且 \(S\) 的某个后缀 \(p\in B_n\) 构成的集合。
给定 \(n,k\),求所有 \(C_n\) 中含恰好 \(k\) 个数字字符的字符串的数量,答案对 \(4\) 取余。
多测。
\(T\leq 10, n\leq 10^{12}, n+2\leq k\leq 2\times 10^{12}\)
神人题目,出抽象大分讨。
二进制位从 \(1\) 开始编号,称一个可以填 \(0/1\) 的位为“自由元”。只要存在至少 \(2\) 个自由元,这个方案一定被计算 \(4k\) 次从而对答案无影响。设最长数字连续段的长度为 \(L\)。
Case 1. \(L > n+2\)
第 \(n+1\) 位与第 \(n+2\) 位一定是自由元,所以根据前述,此时无影响。
如果该段右侧的有连续段长度超过 \(n\),那么就只需要考虑那个后缀即可,现在本段就有 \(L-1\) 个自由元了。
Case 2. \(L = n+2\)
第 \(n+1\) 位一定为自由元,若右侧有一个长度为 \(x\) 的连续段,则此时 \(L\) 对应段的第 \(x\) 位也是自由元,那么就没有影响了。
如果左侧有一个长度为 \(x(x>1)\) 的连续段,那么这个段的第 \(1\) 位一定是自由元,加上 \(L\) 对应段的第 \(n+1\) 位,也没有影响了。
所以本情况内只存在 \(2\) 种可能:长度 \(n+2\) 的连续段在最右侧,左边是 1|1|...|1 的形式。列举一下吧:
1|1|1|...|101111...1111|1|1|...|111111...111
一样的,如果该段右侧的有连续段长度超过 \(n\),那么就只需要考虑那个后缀即可,现在本段就有 \(L-1\) 个自由元了。
Case 3. \(L = n\)
若存在两个长度分别为 \(x,y(1\leq x < y < n)\) 的连续段,那么长度为 \(L\) 的连续段的第 \(x\) 位与第 \(y\) 位都是自由元,进而无影响。
若存在一个长度为 \(x(1\leq x < n)\) 的连续段且存在至少 \(2\) 个长度为 \(L\) 的连续段,这两个连续段的第 \(x\) 位都是自由元,进而无影响。
所以只存在两种可能的情况满足条件:
- 所有连续段的长度均为 \(n\)。
- 仅存在一个长度为 \(n\) 的连续段,以及其余所有长度为 \(h(h < n)\) 的连续段。
先计算前者,肯定需要 \(n\mid k\),总共包含 \(g = \frac{k}{n}\) 个段,每个段的第 \(n\) 位固定,其余每一位都必须要在 \(g\) 组中至少含一个 \(1\),而 \(n-1\) 个位互相独立,列式得 \((2^g - 1)^{n-1}\)。
而计算后者,枚举 \(h\),总共包含 \(g = \frac{k-n}{h}\) 个短的段,加上这个长度为 \(L\) 的段共计 \(g+1\) 个,显然 \(h\mid (k-n)\) 才可行。最长段的第 \(h\) 位可以填 \(0/1\),第 \(h+1\) 位至第 \(n\) 位肯定都要填 \(1\),而第 \(1\) 位至第 \(h-1\) 位类比前者,\(g+1\) 组中至少含一个 \(1\),而 \(h-1\) 个位互相独立。当然,这个最长段可以是 \(g+1\) 段中的任意一个,列式得 \(2(2^{g+1} - 1)^{h-1}(g+1)\)。
分析一下后者的式子,如果 \(g+1\) 为偶数就一定是 \(4\) 的倍数了,显然只需要考虑 \(g+1\) 为奇数,即 \(g\) 为偶数的情况。所以 \(2\mid \frac{k-n}{h}\),变形得 \(h\mid \frac{k-n}{2}\),当然不要忘记 \(h < n\) 的限制,并且自然而然有 \((k-n)\) 为偶数,否则无需考虑。
枚举约数,注意这里的 \(2\) 倍,可以做到 \(\mathcal{O}(\sqrt{k-n})\)。
Case 4. \(L = n+1\)
演都不演直接列式,答案为 \(\overset{k-n}{\underset{i=1}{\sum}} f(i-1)g(k-i)\),其中 \(f(x)\) 表示含 \(x\) 个数字的表达式中有多少个只含至多 \(1\) 个自由元,而 \(g(x)\) 表示含 \(x+1\) 个数字的表达式中,有多少个以一个长度为 \(n+1\) 的段开头,且含有属于 \(B_n\) 的后缀。
先计算 \(f(x)\) 的值,由于这里不需要管什么后不后缀的,只要有一个长度 \(x(x > 1)\) 的连续段就增加 \(x-1\) 个自由元,于是就只有两种形式:
1|1|1|...|1。1|1|1|...|1|1?|1|...|1,其中?表示可以填 \(0/1\)。
前者只有一种,而后者有 \(x-1\) 个连续段,所以有 \(x-1\) 种排布方式且每种方式对应 ? 填 \(0\) 还是填 \(1\) 的两种方案,总计 \(2(x-1) + 1 = 2x-1\)。特别的,\(f(0) = 1\)。
再计算 \(g(x)\) 的值,可以考虑分讨开头那一段的形态:
100...00,也就是除了第 \(n\) 位为 \(1\) 其余全 \(0\),刨去这一段的 \(x-n\) 个数,需要重新得到一个属于 \(B_n\) 的后缀,等价于整个 Case 3 的结果。- 答案为 \(2(2^{g+1}-1)^{h-1}(g+1) + (2^{(x-n)/n} - 1)^{n-1}\),其中 \(g= \frac{x-2n}{h}\)。
- \(g\) 的取值要在 \(x-n\) 个数中再拿出一个长度为 \(n\) 的连续段,所以短段中的数字只有 \(x-2n\) 个。
- 至于 \(g+1\) 就是因为一个长度为 \(n\) 的段也算在内,但是长度为 \(n+1\) 的段不算。
11??...??,也就是第 \(n\) 位与第 \(n+1\) 位均为 \(1\),这也基本等价于整个 Case 3 的结果,只不过在计算 3.2 的时候最长段一定要在最左侧。- 答案为 \(2(2^{g + 1}-1)^{h-1} + (2^{x/n} - 1)^{n-1}\),其中 \(g = \frac{x-n}{h}\)。
- 取 \(g+1\) 在 4.1 中已经讨论清晰。
10??...?1?...?,也就是第 \(n\) 位为 \(0\),第 \(n+1\) 位为 \(1\),中间至少有一个还有一个 \(1\),相当于把最开头的1刨去做 3.2。- 答案为 \(2(2^{g+2}-1)^{h-1}(g+1)\),其中 \(g= \frac{x-2n}{h}\)。
- \(g\) 的取值在 4.1 中已经讨论清晰。
- 至于 \(g+2\) 就是因为一个长度为 \(n\) 的段和一个长度为 \(n+1\) 的段都算在内。
特别的,注意 \(g(n) = 1\),所以单独加上 \(f(k-n-1)\)。
考虑这五个不同的式子,拿出来:
- \(A = 2(2^{(x-2n)/h+1}-1)^{h-1}((x-2n)/h+1)\)
- \(B = (2^{(x-n)/n} - 1)^{n-1}\)
- \(C = 2(2^{(x-n)/h + 1}-1)^{h-1}\)
- \(D = (2^{x/n} - 1)^{n-1}\)
- \(E = 2(2^{(x-2n)/h+2}-1)^{h-1}((x-2n)/h+1)\)
考虑 \(A + E = 2((x-2n)/h+1)((2^{(x-2n)/h+1}-1)^{h-1} + (2^{(x-2n)/h+2}-1)^{h-1})\),显然最右边的括号内是两个奇数相加,所以 \(A+E\) 恒为 \(4\) 的倍数,仅需 \(x > 2n\) 即可。
对于 4.1 与 4.3,考虑 \(x = 2n\) 时,长度为 \(L+1\) 段的中的如果恰好一个 1 增加一个自由元,总计 \(2(n-1)\) 种方案,需要单独计算。
考虑 \(B + D + [x=2n]2(n-1)\),要么是 \(x=2n\) 时取 \(2(n-1) + 1^{n-1} + 3^{n-1}\),否则 \(x=kn(k > 2)\) 取 \(2\times 3^{n-1}\),讨论得 \(B + D + [x=2n]2(n-1)\) 恒取 \(2\)。
于是这里总共有 \(\lfloor{\frac{k-1}{n}}\rfloor-1\) 个 \(2\)。
考虑 \(C\),类比 Case 3 所说,相当于要求 \(x-n\) 的约数 \(h\) 且 \(h < n\) 的个数,由于 \(x = k-i\in [n+1,k-1]\),所以 \(x-n\in [1,k-n-1]\),进而相当于要求:
枚举 \(j\) 得到整除分块形式:
直接做即可,不要忘记这里的 \(2\) 倍,本部分时间复杂度为 \(\mathcal{O}(\sqrt{k-n})\)。
Question 11. [ICPC 2016 WF] Branch Assignment
给定一个 \(n\) 个点 \(m\) 条边的有向强连通图,其中编号为 \(1\sim b\) 的点是关键点,将 \(b\) 个关键点划分为 \(s\) 个互不交的点集,若点 \(i\) 与点 \(j\) 在同一点集则增加 \(d(i,b+1)+d(b+1,j)\) 的代价,其中 \(d(a,b)\) 表示 \(a\to b\) 的最短路,求最小代价。
\(s\leq b < n\leq 5000\)
首先对于一个点集 \(S\),考虑贡献式为 \(\sum_{i\ne j\in S} d(i,b+1)+d(b+1,j) = \sum_{i\in S} d(i,b+1) \sum_{j\ne i} 1 + \sum_{i\in S} d(b+1,i) \sum_{j\ne i} 1 = (|S| -1)\sum_{i\in S}(d(i,b+1)+d(b+1,i))\)。
于是令 \(c_i = d(i,b+1) + d(b+1,i)\),在正反图上分别跑最短路容易求得,贡献式变为 \((|S| - 1)\sum_{i\in S} c_i\)。
感受一下点集划分的策略:\(c_i\) 小的可以叠一起,把 \(|S|\) 搞大一点,启发我们按照 \(c_i\) 排序,于是每个 \(S\) 应该是一段区间。
考虑暴力 DP,设 \(f_{i,j}\) 表示前 \(i\) 个点划分 \(j\) 个点集的最小代价,枚举 \(k\) 表示第 \(j-1\) 个点集的结束点转移 \(f_{i,j}\gets f_{k,j-1} + (i-k-1)(S_i-S_k)\) 即可,其中 \(S\) 为 \(c\) 的前缀和。时间复杂度为 \(\mathcal{O}(n^3)\),显然跑不动。
考虑优化,打表知这个答案关于 \(s\) 有凸性,于是丢一个 wqs 二分,时间复杂度为 \(\mathcal{O}(n^2\log_2 V)\)。又打表知代价满足四边形不等式于是可以决策单调性优化,时间复杂度为 \(\mathcal{O}(n^2\log_2 n)\)。两个优化一起可以做到 \(\mathcal{O}(n\log_2 n\log_2 V)\)。
二分队列的决策单调性优化的细则见 OI-wiki,这里只概述核心思想:在单调队列中按照 \(l\) 升序维护的三元组 \((l,r,j)\),表示决策点 \(j\) 转移区间 \([l,r]\),每次先去除 \(r < i\),而后判定队尾决策是否更劣。
Question 12. [IOI 2000] 邮局
数轴上有 \(N\) 个点,你需要在其中选择 \(M\) 个点进行标记,最小化每个点到其最近的标记点的距离之和。
\(M\leq N\leq 10^5\)
先把点的坐标升序排个序,于是可以考虑设 \(f_{i,j}\) 表示前 \(i\) 个点标记了 \(j\) 个点,枚举上一个标记点所控制的段的末尾点 \(k\)。
容易发现,如果一个标记点控制区间 \([l,r]\),肯定取 \([l,r]\) 的中间点 \(p\),代价容易利用前缀和 \(\mathcal{O}(1)\),记为 \(c(l,r)\)。
那么 DP 的转移显然是 \(f_{i,j} = \min_{k < i} f_{k,j-1} + c(k+1,i)\)。
考虑优化,打表知这个答案关于 \(M\) 有凸性,于是丢一个 wqs 二分,时间复杂度为 \(\mathcal{O}(N^2\log_2 V)\)。又打表知代价满足四边形不等式于是可以决策单调性优化,二分队列做到 \(\mathcal{O}(N\log_2 N\log_2 V)\)。
Question 13. 「JOI 2016 Final」领地
Kaho 从 \((0,0)\) 出发,按照一个指定的移动方式 \(S\) 进行移动,其中 \(S\) 是一个长度为 \(N\) 的字符串,每一个字符是东西南北中的一个移动方向,Kaho 会按照顺序向 \(S_i\) 指示的方向移动一步。
接下来的 \(K\) 天,第一天从 \((0,0)\) 出发,之后的每一天都会从前一天的停止点按照 \(S\) 继续移动。
Kaho 占领了一个格子,当且仅当存在正整数 \(a,b\),使得 \((a,b),(a+1,b),(a,b+1),(a+1,b+1)\) 都在 Kaho 的移动路径上,则以这四个点为顶点的正方形格子被 Kaho 占领。
计算最终 Kaho 占领了多少个格子。
\(N\leq 10^5, K\leq 10^9\)
假设第一天结束后,Kaho 在 \((x,y)\) 位置,那么这便是移动方向向量,记为 \((x_D,y_D)\),不失一般性的可以设 \(x_D > 0, y_D\ge 0\),具体操作可以对 \(S\) 进行一些小小修改,那么 Kaho 移动时的某个位置 \((x,y)\) 可以唯一表示成 \((p + x_D t, q + y_D t)\),其中 \(p\in [0,x_D)\)。
由于 Kaho 每天的移动路径是一样的,那么 Kaho 的位置一定满足 \((p,q)\) 可以在第一天的位置中找到(包括起始点 \((0,0)\)),所以 Kaho 的位置一定满足 \((p,q,l,r)\),其中 \(l\leq t\leq r\) 而实际位置即 \((p + x_D t , q + y_D t )\)。
总计 \(\mathcal{O}(N)\) 个不同的 \((p,q)\) 则可以确定 \(\mathcal{O}(N)\) 个区间,将这些区间按照 \((p,q)\) 进行分类。
考虑一个正方形,在一个 \(t\) 下,如果 \(p,q\) 是合法的那么就增加 \(1\) 的贡献(注意可能会遇到 \(p = x_D - 1\),此时 \(p + 1 = x_D\) 需要 \(t + 1\)),那么可以改为枚举 \(p,q\),将对应四顶点的区间组归并求交,交集的大小就是以 \((p,q)\) 为某一指定顶点的 \(t\) 的数量,也即 \((p,q)\) 带来的贡献的总和。
预处理出按照 \((p,q)\) 分类的区间组可以做到 \(\mathcal{O}(N\log_2 N)\),每个区间组最多在 \(4\) 个顶点处各被计算一次共 \(4\) 次,区间组的总大小是 \(\mathcal{O}(N)\) 的,于是暴力做的复杂度为 \(\mathcal{O}(N)\),综上总时间复杂度为 \(\mathcal{O}(N\log_2 N)\)。
Question 14. 「JOI Open 2019」汇款
\(N\) 个账户编号 \(0\sim N - 1\),第 \(i\) 个账户的余额为 \(A_i\),目标存款为 \(B_i\),每一次可以执行如下操作:
- 选择一个账户 \(u\),令 \(v = (u+1)\bmod N\),让 \(u\) 给 \(v\) 转账 \(X\) 元,同时从账户 \(u\) 余额中扣除 \(X\) 元手续费,此时 \(2X\) 必须不大于当前账户 \(u\) 的余额。
请问是否可行?
\(2\leq N\leq 10^6, A_i, B_i\leq 10^9\)
首先感受出贪心:每次将第 \(i\) 个账户扣除到不高于 \(B_i\) 或者 \(\leq 1\) 元,反复执行操作直至不能操作,可以通过前两个子任务。
可以感受出每次大量的钱是按照 \(0,1,2,\cdots,N-1\) 的顺序移动,于是改到环上顺次进行操作,直至不能操作,过了。
为什么?正确性从何而来?复杂度如何保证?
感受其正确性:显然一个账户向下一个账户转账的总额是确定的,这样可以尽量保证自己有更多的余额以供后续操作,在所有位置都都不低于 \(B_i\) 或者因为 \(B_i = 0\) 卡在 \(1\) 之前,一定可以不断进行调整。
计算其复杂度:假设我们在操作一圈之后,多余的钱一定基本会在同一个位置上,考虑这个位置的 \(D = A_i - B_i\),而且 \(D\) 一定会是最大的 \(A_i - B_i\),若 \(D\ge 2\),则每进行一次操作,\(D\) 会砍半,除非 \(V=2, B_i = 0, A_i = 1\) 会不变,但是这样再转一圈就能够知道结果。毕竟全部都是 \(A_i = 1, B_i = 0\) 也会卡住就没必要继续转了。
所以,反复执行操作直至无法操作,只会判定 \(\mathcal{O}(N + \log_2 V)\) 轮。故时间复杂度正确。
Question 15. 「JOI 2020 Final」集邮比赛 3
周长为 \(L\) 米的环形湖边有 \(N\) 个集邮点,第 \(i\) 个点位于从出发点顺时针 \(X_i\) 米处,在出发后的 \(T_i\) 秒以内可以在该点集邮。
从出发点出发的 Hinata-Chan 每个时刻可以顺时针或逆时针行动 \(1\) 米,请问她能够收集到的邮票的数量的最大值是多少?
\(N\leq 200, L,T_i\leq 10^9, X_i < X_{i+1}\)
破环为链然后倍长,现在出发点位于第 \(N\) 个点与第 \(N+1\) 个点之间。
最显然的 DP 式子就是设 \(f_{l,r,t,0/1}\) 表示在时刻 \(t\) 扩展了区间 \([l,r]\) 内的所有集邮点,当前位于集邮点 \(l\) 还是 \(r\),收集到的邮票的数量的最大值。
每次考虑扩展到集邮点 \(l-1\) 还是 \(r+1\)。
但是 \(t\) 很大,而 \(f_{l,r,t,0/1}\) 的值很小,考虑对换位置,即设 \(g_{l,r,k,0/1}\) 表示扩展了区间 \([l,r]\) 内的所有集邮点并收集了 \(k\) 张邮票,当前位于集邮点 \(l\) 还是 \(r\),所花时间的最小值。
每次仍然是考虑扩展到集邮点 \(l-1\) 还是 \(r+1\),并通过 dp 值计算能否拿到。显然不需要考虑故意不拿到的情况,因为这样肯定更劣。
初始仅需要考虑 \(l = r = n\) 以及 \(l = r = n+1\),最终对所有转移到的 \(g_{l,r,k,0/1}\) 取 \(k\) 的最大值即为答案。时间复杂度为 \(\mathcal{O}(N^3)\)。
Question 16. 「JOISC 2013 Day2」间谍
JOI 公司与 IOI 公司分别有 \(N\) 个员工,两个公司内部的 \(N\) 个人都构成树形的上司-下属关系,IOI 公司的员工 \(t\) 负责监视 JOI 公司的员工 \(t\)。
当某个公司内部的某个员工 \(x\) 获得一个任务后,该公司中员工 \(x\) 的直接与间接下属都会开始执行该任务。
现在有 \(M\) 个项目及其对应的间谍项目,JOI 公司的员工 \(p_i\) 获得第 \(i\) 个项目,而 IOI 公司的员工 \(q_i\) 获得第 \(i\) 个项目的间谍项目。
如果 JOI 公司的员工 \(a\) 执行一个项目 \(x\),而 IOI 公司的员工 \(a\) 执行了项目 \(x\) 的间谍项目,那么 IOI 公司的员工 \(a\) 就完成了一次间谍活动。
对 IOI 公司中的每一个员工求出他完成了几次间谍活动。
\(N\leq 2000, M\leq 5\times 10^5\)
首先可以想到的就是遍历两棵子树,如果遇到有相同编号 \(p\) 则对应答案加,时间复杂度为 \(\mathcal{O}(MN^2)\)。
那么因为没有形成监视的不会对任何答案造成影响,所以我们可以直接对两棵子树的所有员工组合 \((i,j)\) 的 \(s_{i,j}\) 加 \(1\),然后答案直接查 \(s_{i,i}\) 值。
子树可以拍到 dfs 序上,于是就是横纵坐标一段区间构成的矩形加,二维差分优化即可。时间复杂度为 \(\mathcal{O}(M+N^2)\)。
Question 17. 「JOI 2019 Final」有趣的家庭菜园 3
JOI 先生家里养了 \(N\) 盆 Joy 草,初始从左往右第 \(i\) 盆草开的花的颜色为 \(S_i\),花总共只可能是红黄绿三种颜色。
为了让 Joy 草顺利成长,JOI 先生希望相邻两盆草开不同颜色的花。但是花盆真的很重,所以 JOI 先生每次只可以交换相邻两盆 Joy 草。
请问 JOI 先生完成目标的最少次数是多少?
\(N\leq 400\)
首先交换相邻两个数,这启发我们用跟冒泡排序相关的逆序对来刻画,次数也就是相当于最终所得到的序列的逆序对数量,而初始状态就是 \(1\sim N\) 顺次排列。
现在就可以考虑 DP 了,设 \(f_{i,j,k,0/1/2}\) 表示最终的前 \(i\) 盆 Joy 草有 \(j\) 盆开红花,\(j\) 盆开绿花,而 \(i-j-k\) 盆开黄花,第 \(i\) 盆是什么颜色。
转移则考虑第 \(i + 1\) 盆放的颜色 \(c\),假设这是第 \(X_c\) 盆颜色 \(c\) 的花,而初始状态下第 \(X_c\) 盆颜色 \(c\) 的花位于位置 \(p\),那么逆序对数量就肯定是对每种颜色 \(c'\) 求:前 \(i\) 盆花中该颜色的花的数量减去初始前 \((p-1)\) 盆花中该颜色的花的数量,与 \(0\) 取 \(\max\) 后累加。通过预处理初始状态下每种花的颜色数量的前缀和、以及每种花的出现位置,可以做到 \(\mathcal{O}(N^3)\)。
当然空间不一定够,滚动数组优化即可。

浙公网安备 33010602011771号