P11030 『DABOI Round 1』Blessings Repeated题解

P11030 『DABOI Round 1』Blessings Repeated题解

【形式化题意】

给定一个正整数 k 和两个字符串 S,T

设字符串 sk 个字符串 S 首尾相接得到的字符串,n=|s|,m=|T|

设答案集合 P={(i0,i1,,im1)0i0<i1<<im1<n, 0j<m,sij=Tj},请求出 |P|mod998244353

输入格式

输入共 3 行。

11 个整数,表示 k

21 个字符串,表示 S

31 个字符串,表示 T

输出格式

输出共 11 个整数,表示答案。

样例 #1

样例输入 #1

2
stocyhorz
cyh

样例输出 #1

4

样例 #2

样例输入 #2

4
c
ccc

样例输出 #2

4

提示

【样例 1 解释】

S 重复 2 次得到 stocyhorzstocyhorz

答案集合 P={(3,4,5),(3,4,14),(3,13,14),(12,13,14)},因此 |P|=4


【数据范围】

对于 100% 的数据,0<k10180<|S|5×1030<|T|10,字符串 S,T 均由小写英文字母组成。

Point k |S| |T|
12 1018 5×103 1
3 1 5×103 2
45 100 5×103 2
67 1 50 4
810 10 5×103 10
1120 1018 5×103 10

赛时想法

想到了做一个 dp ,但是一上来就把阶段丢掉了,导致把自己绕晕了,大概想的是定义 dp[i] 为:如果 S 的当前位置位在 T 中,那么选完了这一位以后对应的方案数 ,i 代表 T 中对应的第 i 个字符。转移的时候就统计前缀和就行,但这样的想法很容易被 hack 掉,还是我太菜了,很显然的一个例子是 T=aaa ,当我们枚举到 S 中某位是 a 时,dp[2] 会从 dp[1] 进行转移,因此会多统计出来一部分。

正解

重新定义 dp[i][j] 为考虑完 S 中前 i 个后,选完 T 串中第 j 个位置的方案数,那么转移方程也十分的明显了。

dp[i][j]={dp[i1][j],S[i]!=T[j]dp[i1][j]+dp[i1][j1],S[i]==T[j]

发现 k 的数据范围尤其的大,基本上要么就是推数学结论,要么就是矩阵加速递推,现在 dp 都写出来了,这下不得不递推了。

核心思想

和普通的矩阵加速不同(很大可能是我刷的题太少了),本题的 dp 是带条件的,也就是说,在某一个循环内枚举的时候,有可能会有很多个不同的转移矩阵。

但最重要的地方在于,这些转移矩阵的出现是有规律的,如(A1A2...An)...(A1A2...An) 一共有 k 个这样的循环,那么我们记每一个循环根据结合律得出的转移矩阵是 Sup ,总的转移矩阵就是 Supk

最后在初始 dp 矩阵右乘上一个 Supk 就好了。

容易犯错的地方

注意 dp[0] 的初值应该赋为 1 ,不然答案为 0 了。

然后还有就是,由于每一个循环节内的子转移矩阵是不同的,所以累乘的方式应该根据 dp 是左乘还是右乘转移矩阵有所变化,比如下面给出的代码是左乘转移矩阵,那么在预处理的时候也应该从左边乘进来,类似于一个栈的结构。

posted @   Hanggoash  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
动态线条
动态线条end
点击右上角即可分享
微信分享提示