0%

The 2025 Jiangsu Collegiate Programming Contest(2025 江苏省赛)——H. Loose Subsequences(求本质不同子序列的方法)

题目大意

题目描述
给定一个长度为 nn、仅由小写字母组成的字符串 SS 以及一个非负整数 kk
需要计算 SS 的本质不同的非空 kk-松散子序列的数量,并将结果对 998244353998244353 取模。

相关定义

  • kk-松散子序列:如果子序列 TT 在原字符串 SS 中对应的下标序列为 pos1,pos2,,posmpos_1, pos_2, \dots, pos_m,且满足对于所有的 i[1,m1]i \in [1, m-1],都有 posi+1posi>kpos_{i+1} - pos_i > k,那么 TT 就是一个 kk-松散子序列。即子序列中原串相邻提取字符的原始位置距离必须严格大于 kk

  • 本质不同:两个子序列被认为是不同的,当且仅当它们的长度不同,或者它们在某个对应位置上的字符不相同(即只对比提取出的字符构成的字符串本身是否一致)。

输入格式
第一行包含一个整数 TT1T1061 \le T \le 10^6),表示测试用例数。
对于每组测试用例:
第一行包含两个整数 n,kn, k1n106,0kn1 \le n \le 10^6, 0 \le k \le n)。
第二行包含一个长度为 nn 的字符串 SS,保证仅包含小写字母。
保证所有测试用例的 n106\sum n \le 10^6

输出格式
对于每组测试用例,输出一行一个整数,表示本质不同的非空 kk-松散子序列的数量对 998244353998244353 取模的结果。

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
输入:
3
4 1
aabb
5 2
abcab
7 3
abcdece

输出:
3
6
10

样例解释

  • 对于第一个测试用例(S=aabbS = \text{aabb}k=1k = 1),下标位置差必须严格大于 11。满足条件的本质不同的子序列有 abab

  • 对于第二个测试用例(S=abcabS = \text{abcab}k=2k = 2),下标位置差必须严格大于 22。满足条件的本质不同的子序列有 abcaaabbb

思路讲解

呃,这个我们需要想办法做到求本质不同的这个所有子序列

我们转移的时候,就是应该以 s[i] 开头的串,在我们所有的这个的计数之中,应该以 s[i] 开头的串只应该真的以 i 开头的时候被计算,因此后面的应该被减去。(当然,我们是从后往前遍历)

具体而言,这个转移式子是:

next[i]存在: dp[i]2×dp[i+1](dp[next[i]+1]+1)+1dp[i]2×dp[i+1]dp[next[i]+1]next[i]不存在: dp[i]2×dp[i+1]+1next[i] 存在:\ dp[i]\gets 2\times dp[i+1]-(dp[next[i]+1]+1)+1 \\ dp[i]\gets 2\times dp[i+1]-dp[next[i]+1] \\ next[i] 不存在:\ dp[i]\gets 2\times dp[i+1]+1

注意,为什么是减去 dp[next[i]+1]+1dp[next[i]+1]+1 呢?因为其实这个才是含有 next[i]next[i] 的子序列的所有数量。

当然,这个是求本质不同的这个子序列的时候,我们要计算 k-松散子序列。

计算 k-松散子序列:

next[i]不存在: dp[i]2×dp[i+k+1]+1next[i]存在: dp[i]2×dp[i+k+1]+1(dp[next[i]+k+1]+1)dp[i]2×dp[i+k+1]dp[next[i]+k+1]next[i] 不存在:\ dp[i]\gets 2\times dp[i+k+1]+1 \\ next[i] 存在:\ dp[i]\gets 2\times dp[i+k+1]+1-(dp[next[i]+k+1]+1) \\ dp[i]\gets 2\times dp[i+k+1]-dp[next[i]+k+1]

AC代码

心路历程(WA,TLE,MLE……)