Solution
Solution
2025 年四川省大学生程序设计竞赛题解
SCCPC2025 solution
hdu 出题组
杭州电子科技大学
2025.6.8
难度
easy: IFJKH
middle: ACED
hard: LBG
I - 本质不同后缀
给定 N 个字符串,求这些字符串本质不同的后缀个数。
∑
N ≤ 3 × 105 , |Si | ≤ 3 × 105 。
I - 本质不同后缀
每个串翻转过来,变成本质不同的前缀个数。
I - 本质不同后缀
每个串翻转过来,变成本质不同的前缀个数。
可以通过直接把反串插入 trie 树,输出节点个数 −1 即可,
也可以通过别的字符串算法通过本题。
I - 本质不同后缀
每个串翻转过来,变成本质不同的前缀个数。
可以通过直接把反串插入 trie 树,输出节点个数 −1 即可,
也可以通过别的字符串算法通过本题。
∑
时间复杂度 O( |Si |)。
F - 逆序对
给一个挖空的 01 串,填空后最小化串的逆序对数量。
∑
n ≤ 106 , n ≤ 2 × 106 。
F - 逆序对
F - 逆序对
F - 逆序对
F - 逆序对
F - 逆序对
J - 四川省赛
J - 四川省赛
本题的可行做法有很多。
J - 四川省赛
本题的可行做法有很多。
一个可行的做法是树形 DP,设 fi,j 表示从 i 的子树中某个
点到 i 匹配 SCCPC 长度为 j 的前缀的方案数,gi,j 相应表示
后缀的方案数。转移和计算答案类似于树直径 DP 一样,细
节较多。
J - 四川省赛
本题的可行做法有很多。
一个可行的做法是树形 DP,设 fi,j 表示从 i 的子树中某个
点到 i 匹配 SCCPC 长度为 j 的前缀的方案数,gi,j 相应表示
后缀的方案数。转移和计算答案类似于树直径 DP 一样,细
节较多。
另一个可行的做法是枚举中间点,此时两边均只有两个字
符,找每个点出发匹配多少个 CS 和 PC 即可计算前后缀的
方案数合并得到中间点确定的答案。注意此时 PC 会算重。
J - 四川省赛
本题的可行做法有很多。
一个可行的做法是树形 DP,设 fi,j 表示从 i 的子树中某个
点到 i 匹配 SCCPC 长度为 j 的前缀的方案数,gi,j 相应表示
后缀的方案数。转移和计算答案类似于树直径 DP 一样,细
节较多。
另一个可行的做法是枚举中间点,此时两边均只有两个字
符,找每个点出发匹配多少个 CS 和 PC 即可计算前后缀的
方案数合并得到中间点确定的答案。注意此时 PC 会算重。
时间复杂度 O(n)。
K - 点分治
给定排列表示点分治每次分治的中心,问最后点分树上每个
点的父亲。
∑
n ≤ 105 , n ≤ 106 。
K - 点分治
点分治的过程可以看成,每次在连通块内删除一个点,分裂
出来的每个连通块的父亲即这个点,即把分裂出来的每个连
通块的根的父亲设为这个点。
K - 点分治
点分治的过程可以看成,每次在连通块内删除一个点,分裂
出来的每个连通块的父亲即这个点,即把分裂出来的每个连
通块的根的父亲设为这个点。
正着做很难知道分裂后每个连通块的根,不妨考虑倒着做。
K - 点分治
点分治的过程可以看成,每次在连通块内删除一个点,分裂
出来的每个连通块的父亲即这个点,即把分裂出来的每个连
通块的根的父亲设为这个点。
正着做很难知道分裂后每个连通块的根,不妨考虑倒着做。
倒着做后,每次枚举到一个新的点 pi ,相当于把这个点加入
图中,并且合并其在原树上相邻的当前已经存在的连通块,
这些连通块的根的父亲即当前点 pi ,之后 pi 就成为了合并
后连通块的根。
K - 点分治
点分治的过程可以看成,每次在连通块内删除一个点,分裂
出来的每个连通块的父亲即这个点,即把分裂出来的每个连
通块的根的父亲设为这个点。
正着做很难知道分裂后每个连通块的根,不妨考虑倒着做。
倒着做后,每次枚举到一个新的点 pi ,相当于把这个点加入
图中,并且合并其在原树上相邻的当前已经存在的连通块,
这些连通块的根的父亲即当前点 pi ,之后 pi 就成为了合并
后连通块的根。
∑
并查集实现即可,时间复杂度 O( n log n)。
H - 胡图图
H - 胡图图
两维可以拆开来独立考虑。
H - 胡图图
两维可以拆开来独立考虑。
会发现如果可以 c 步从 x 走到 X,那么 c + 2, c + 4, · · · 都
可以(可以来回浪费 2 步)。
H - 胡图图
两维可以拆开来独立考虑。
会发现如果可以 c 步从 x 走到 X,那么 c + 2, c + 4, · · · 都
可以(可以来回浪费 2 步)。
因此答案为:
H - 胡图图
两维可以拆开来独立考虑。
会发现如果可以 c 步从 x 走到 X,那么 c + 2, c + 4, · · · 都
可以(可以来回浪费 2 步)。
因此答案为:
H - 胡图图
两维可以拆开来独立考虑。
会发现如果可以 c 步从 x 走到 X,那么 c + 2, c + 4, · · · 都
可以(可以来回浪费 2 步)。
因此答案为:
H - 胡图图
两维可以拆开来独立考虑。
会发现如果可以 c 步从 x 走到 X,那么 c + 2, c + 4, · · · 都
可以(可以来回浪费 2 步)。
因此答案为:
A - 最小乘积
A - 最小乘积
不难想到设计
∑ DP∑状态 fsum,u 表示目前到达 u 节点且
ai = sum 时, bi 的最小值。
A - 最小乘积
不难想到设计
∑ DP∑状态 fsum,u 表示目前到达 u 节点且
ai = sum 时, bi 的最小值。
注意到 ai > 0,sum 相同的状态之间没有转移。
A - 最小乘积
不难想到设计
∑ DP∑状态 fsum,u 表示目前到达 u 节点且
ai = sum 时, bi 的最小值。
注意到 ai > 0,sum 相同的状态之间没有转移。
所以可以直接枚举 sum 再枚举可行的边,直接转移。
A - 最小乘积
不难想到设计
∑ DP∑状态 fsum,u 表示目前到达 u 节点且
ai = sum 时, bi 的最小值。
注意到 ai > 0,sum 相同的状态之间没有转移。
所以可以直接枚举 sum 再枚举可行的边,直接转移。
时间复杂度 O(NM max{ai })。
C - 最优时间
{ ⌊ ⌋}
N
S(x) = {d | d | x} ∪ kx | 2 ≤ k ≤
x
假设当前状态是 x,每秒可以决定等概率变成 S(x) 中的一
个数,或者保持不变,每秒结束后 x ← x − 1,给定初始状
态 x,需要求出最优决策下到 0 的期望时间。
N ≤ 105 。
C - 最优时间
这个问题直接做并不容易做,考虑迭代做法。
C - 最优时间
这个问题直接做并不容易做,考虑迭代做法。
(k)
假设 fi 是迭代 k 轮之后 fi 的值。
C - 最优时间
这个问题直接做并不容易做,考虑迭代做法。
(k)
假设 fi 是迭代 k 轮之后 fi 的值。
(0)
初始时 = i,也就是每一秒都保持不变,等待 i 秒之后自
fi
动变成 0。
C - 最优时间
这个问题直接做并不容易做,考虑迭代做法。
(k)
假设 fi 是迭代 k 轮之后 fi 的值。
(0)
初始时 = i,也就是每一秒都保持不变,等待 i 秒之后自
fi
动变成 0。
每一轮迭代的式子为:
∑
(k)
j∈S(i) fj−1
= min fi−1 ,
(k+1) (k)
fi +1
|S(i)|
C - 最优时间
这个问题直接做并不容易做,考虑迭代做法。
(k)
假设 fi 是迭代 k 轮之后 fi 的值。
(0)
初始时 = i,也就是每一秒都保持不变,等待 i 秒之后自
fi
动变成 0。
每一轮迭代的式子为:
∑
(k)
j∈S(i) fj−1
= min fi−1 ,
(k+1) (k)
fi +1
|S(i)|
目标是 f∞,i 。
C - 最优时间
证明这个迭代是收敛的:
C - 最优时间
证明这个迭代是收敛的:
(k+1) (k)
单调不增:fi ≤ fi ,对于每个 i 都成立,考虑 k = 0 的
时候,是显然的,又因为
( ∑ (k) ) ( ∑ (k−1) )
(k) j∈S(i) fj−1 (k−1) j∈S(i) fj−1
min fi−1 , +1 ≤ min fi−1 , +1
|S(i)| |S(i)|
做数学归纳,可知单调不增。
C - 最优时间
证明这个迭代是收敛的:
(k+1) (k)
单调不增:fi ≤ fi ,对于每个 i 都成立,考虑 k = 0 的
时候,是显然的,又因为
( ∑ (k) ) ( ∑ (k−1) )
(k) j∈S(i) fj−1 (k−1) j∈S(i) fj−1
min fi−1 , +1 ≤ min fi−1 , +1
|S(i)| |S(i)|
做数学归纳,可知单调不增。
有下界:期望时间一定大于等于 0。
C - 最优时间
在 1 ≤ N ≤ 105 的收敛到 10−6 的次数如下图所示,最大次
数不会超过 100 次,可以迭代 100 次通过本题。
E - 竞赛图
E - 竞赛图
E - 竞赛图
E - 竞赛图
E - 竞赛图
E - 竞赛图
E - 竞赛图
E - 竞赛图
E - 竞赛图
E - 竞赛图
E - 竞赛图
E - 竞赛图
E - 竞赛图
综上,只需要图中存在一个大小至少为 k 的强连通块即可。
E - 竞赛图
综上,只需要图中存在一个大小至少为 k 的强连通块即可。
考虑怎么计算大小为 n 的强连通竞赛图个数,记作 fn ,容斥
计算不连通的方案数,枚举缩点后链末端连通块大小 i,有
n ∑
n−1
n−i
fn = 2(2) − fi × 2( 2 )
i=1
E - 竞赛图
综上,只需要图中存在一个大小至少为 k 的强连通块即可。
考虑怎么计算大小为 n 的强连通竞赛图个数,记作 fn ,容斥
计算不连通的方案数,枚举缩点后链末端连通块大小 i,有
n ∑
n−1
n−i
fn = 2(2) − fi × 2( 2 )
i=1
那么方案数为
1
[xn ]
1 − F(x)
hdu 出题组 杭州电子科技大学
2025 年四川省大学生程序设计竞赛题解
I F J K H A C E D L B G
D - 三分图
对于一个长度为 n 的全排列,以如下方式生成图:
对于 1 ≤ i < j ≤ n,如果 pi > pj ,则有无向边 (i, j)。
若生成图为三分图,则是一个好的全排列。
给出全排列 p,问有多少个好的全排列 q,其字典序大于 p,
答案对 998244353 取模。
T, n ≤ 300。
D - 三分图
D - 三分图
D - 三分图
D - 三分图
先不考虑计数,考虑给出全排列 q 如何作判定性问题,初始
时我们定义一个长度为 3 的序列 f = {0, 0, 0},表示这三个
上升子序列当前末尾元素,依次枚举 i ∈ [1, n],那么 qi 可
以接到这个三元序列中任意一个比它小的位置,从贪心的角
度,我们必然选择最大的那个,如果最终可以把 q1 , · · · , qn ,
全部安放上去,说明是一个好的序列。
D - 三分图
再考虑没有字典序的要求,有多少个长度为 n 的序列。
D - 三分图
再考虑没有字典序的要求,有多少个长度为 n 的序列。
不妨假设 f0 ≤ f1 ≤ f2 ,我们用 DP(a, b, c) 表示剩下的元素
中,有 a 个元素 > f0 ,有 b 个元素 > f1 ,有 c 个元素 > f2
时可以填充的方案数。
D - 三分图
再考虑没有字典序的要求,有多少个长度为 n 的序列。
不妨假设 f0 ≤ f1 ≤ f2 ,我们用 DP(a, b, c) 表示剩下的元素
中,有 a 个元素 > f0 ,有 b 个元素 > f1 ,有 c 个元素 > f2
时可以填充的方案数。
若我们填充了一个 > f1 的元素,假设它是剩下元素中第 x
大的,那么会转移到 DP(x − 1, b − 1, c − 1)。
D - 三分图
再考虑没有字典序的要求,有多少个长度为 n 的序列。
不妨假设 f0 ≤ f1 ≤ f2 ,我们用 DP(a, b, c) 表示剩下的元素
中,有 a 个元素 > f0 ,有 b 个元素 > f1 ,有 c 个元素 > f2
时可以填充的方案数。
若我们填充了一个 > f1 的元素,假设它是剩下元素中第 x
大的,那么会转移到 DP(x − 1, b − 1, c − 1)。
若我们填充了一个 > f2 的元素,从贪心的角度它必然小于
f1 ,假设它是剩下元素中第 x 大的,那么会转移到
DP(a, x − a − 1, c − 1)。
D - 三分图
再考虑没有字典序的要求,有多少个长度为 n 的序列。
不妨假设 f0 ≤ f1 ≤ f2 ,我们用 DP(a, b, c) 表示剩下的元素
中,有 a 个元素 > f0 ,有 b 个元素 > f1 ,有 c 个元素 > f2
时可以填充的方案数。
若我们填充了一个 > f1 的元素,假设它是剩下元素中第 x
大的,那么会转移到 DP(x − 1, b − 1, c − 1)。
若我们填充了一个 > f2 的元素,从贪心的角度它必然小于
f1 ,假设它是剩下元素中第 x 大的,那么会转移到
DP(a, x − a − 1, c − 1)。
若我们填充了一个 > f3 的元素,它只能填充剩下最小的那
个元素,且必须大于 f2 ,转移到 DP(a, b, c − 1)。
D - 三分图
再考虑没有字典序的要求,有多少个长度为 n 的序列。
不妨假设 f0 ≤ f1 ≤ f2 ,我们用 DP(a, b, c) 表示剩下的元素
中,有 a 个元素 > f0 ,有 b 个元素 > f1 ,有 c 个元素 > f2
时可以填充的方案数。
若我们填充了一个 > f1 的元素,假设它是剩下元素中第 x
大的,那么会转移到 DP(x − 1, b − 1, c − 1)。
若我们填充了一个 > f2 的元素,从贪心的角度它必然小于
f1 ,假设它是剩下元素中第 x 大的,那么会转移到
DP(a, x − a − 1, c − 1)。
若我们填充了一个 > f3 的元素,它只能填充剩下最小的那
个元素,且必须大于 f2 ,转移到 DP(a, b, c − 1)。
前两种转移通过前缀和优化后,可以在 O(V3 ) 的时间复杂
度内预处理整个 DP 数组,其中 V 为值域。
hdu 出题组 杭州电子科技大学
2025 年四川省大学生程序设计竞赛题解
I F J K H A C E D L B G
D - 三分图
接下来考虑字典序的要求,类比数位 DP 的思想,我们可以
枚举 p 的每一个前缀 p[1 : x] ,在后面穿插一个比 p[x + 1]
大的元素,后面的后缀任取。此时根据这个前缀,我们可以
确定出到当前位置序列 f 的值以及 a, b, c 的具体参数 O(1)
得到答案,时间复杂度为 O(n2 ),也可以利用前缀和作进一
步优化到 O(n)。
D - 三分图
接下来考虑字典序的要求,类比数位 DP 的思想,我们可以
枚举 p 的每一个前缀 p[1 : x] ,在后面穿插一个比 p[x + 1]
大的元素,后面的后缀任取。此时根据这个前缀,我们可以
确定出到当前位置序列 f 的值以及 a, b, c 的具体参数 O(1)
得到答案,时间复杂度为 O(n2 ),也可以利用前缀和作进一
步优化到 O(n)。
∑
综上,总时间复杂度为 O(V3 + 1≤i≤T ni )。
L - abc
定义区间价值为区间中出现次数最多的字符的出现次数减出
现次数最少的字符的出现次数,字符集大小为 3。
N ≤ 2 × 105 。
L - abc
L - abc
L - abc
L - abc
想要剔除掉某两种字符的区间价值,只需要把这两者出现次
数的最小值再减去即可,可以找到极长的包含这两种字符区
间:
L - abc
想要剔除掉某两种字符的区间价值,只需要把这两者出现次
数的最小值再减去即可,可以找到极长的包含这两种字符区
间:
按照字符集大小为
∑ 2 的做法,我们计算出来的答案是
(max − min)。
L - abc
想要剔除掉某两种字符的区间价值,只需要把这两者出现次
数的最小值再减去即可,可以找到极长的包含这两种字符区
间:
按照字符集大小为
∑ 2 的做法,我们计算出来的答案是
− min)。
(max∑
注意到 (max + min) 其实并不难求,在字符集为 2 的时候
恰好是区间长度。
L - abc
想要剔除掉某两种字符的区间价值,只需要把这两者出现次
数的最小值再减去即可,可以找到极长的包含这两种字符区
间:
按照字符集大小为
∑ 2 的做法,我们计算出来的答案是
− min)。
(max∑
注意到 (max + min) 其实并不难求,在字符集为 2 的时候
恰好是区间长度。 ∑
解方程即可知道 min 的值。
L - abc
想要剔除掉某两种字符的区间价值,只需要把这两者出现次
数的最小值再减去即可,可以找到极长的包含这两种字符区
间:
按照字符集大小为
∑ 2 的做法,我们计算出来的答案是
− min)。
(max∑
注意到 (max + min) 其实并不难求,在字符集为 2 的时候
恰好是区间长度。 ∑
解方程即可知道 min 的值。
∑
剩下的问题只有:求出 0≤i≤j≤N |Si − Sj |,可以使用排序,
计算每个数值对应的系数,可以做到 O(n log n)。
L - abc
想要剔除掉某两种字符的区间价值,只需要把这两者出现次
数的最小值再减去即可,可以找到极长的包含这两种字符区
间:
按照字符集大小为
∑ 2 的做法,我们计算出来的答案是
− min)。
(max∑
注意到 (max + min) 其实并不难求,在字符集为 2 的时候
恰好是区间长度。 ∑
解方程即可知道 min 的值。
∑
剩下的问题只有:求出 0≤i≤j≤N |Si − Sj |,可以使用排序,
计算每个数值对应的系数,可以做到 O(n log n)。
注意对于一段长度为 n 的区间,
0 ≤ maxi {Si } − mini {Si } ≤ n,通过这个可以用前缀和优化
到 O(n)。
B - 三进制
交互题。
定义一个 n 位三进制的加密算法为,将每一位的 012 分别
排列映射。
你可以询问不超过 2 次任意 n 位三进制数在加密下的加法
结果(带最高位且最高位不加密) ,得到每一位的排列映射。
∑
n ≤ 10 , n ≤ 10 。
5 6
B - 三进制
先不管低位进位,那么对于一位加法而言:
0 + 1 ≡ 1 (mod 3)
0 + 2 ≡ 2 (mod 3)
1 + 2 ≡ 0 (mod 3)
B - 三进制
先不管低位进位,那么对于一位加法而言:
0 + 1 ≡ 1 (mod 3)
0 + 2 ≡ 2 (mod 3)
1 + 2 ≡ 0 (mod 3)
注意到只有 1 + 2 的结果和原来的两个加数不同,同时存在
进位,所以如果确定不存在进位,1 次询问可以区分这种情
况和前两种情况。同时不管是哪种情况,我们都可以确定 0
是谁。
B - 三进制
如果确定低位进位了,那么对于一位加法而言:
1 + 0 + 1 ≡ 2 (mod 3)
1 + 0 + 2 ≡ 0 (mod 3)
1 + 1 + 2 ≡ 1 (mod 3)
B - 三进制
如果确定低位进位了,那么对于一位加法而言:
1 + 0 + 1 ≡ 2 (mod 3)
1 + 0 + 2 ≡ 0 (mod 3)
1 + 1 + 2 ≡ 1 (mod 3)
注意到只有 0 + 1 的结果和原来的两个加数不同,同时不存
在进位,所以如果确定存在进位,1 次询问可以区分这种情
况和后两种情况。同时不管是哪种情况,我们都可以确定 2
是谁。
B - 三进制
那么第一次询问我们可以直接问 00 · · · 0 和 11 · · · 1。可以确
定最低位必然不存在低位进位,那么后续的高位是否存在低
位进位就可以通过低位结果得到。
B - 三进制
那么第一次询问我们可以直接问 00 · · · 0 和 11 · · · 1。可以确
定最低位必然不存在低位进位,那么后续的高位是否存在低
位进位就可以通过低位结果得到。
第二次询问,最低位的 1 和 2 只能通过是否溢出来区分,即:
1 + 1 = 02
2 + 2 = 11
B - 三进制
那么第一次询问我们可以直接问 00 · · · 0 和 11 · · · 1。可以确
定最低位必然不存在低位进位,那么后续的高位是否存在低
位进位就可以通过低位结果得到。
第二次询问,最低位的 1 和 2 只能通过是否溢出来区分,即:
1 + 1 = 02
2 + 2 = 11
不妨考虑每一位都通过是否溢出来区分剩下两个数字。
B - 三进制
1 + 1 = 02
1 + 1 + 1 = 10
2 + 2 = 11
1 + 2 + 2 = 12
B - 三进制
1 + 1 = 02
1 + 1 + 1 = 10
2 + 2 = 11
1 + 2 + 2 = 12
能够同时区分上面四种情况:如果没有进位就是情况 1;如
果有进位且这一位是 0 就是情况 2;如果有进位且这一位是
1/2,则通过是否和加数相同区分情况 3/4。
B - 三进制
0 + 0 = 00
1 + 0 + 0 = 01
1 + 1 = 02
1 + 1 + 1 = 10
B - 三进制
0 + 0 = 00
1 + 0 + 0 = 01
1 + 1 = 02
1 + 1 + 1 = 10
能够同时区分上面四种情况:如果有进位就是情况 4;如果
没有进位且这一位是 2 就是情况 3;如果没有进位且这一位
是 0/1,则通过是否和加数相同区分情况 1/2。
G - 丢番图
n ≤ 5 × 104 。
G - 丢番图
G - 丢番图
G - 丢番图
理出 F′ (α),利用多点求值快速计算,时间复杂度为
O(n log n)。