模拟赛Day7(7.27)T3题解
题目描述
定义 \(border(S)\) 为最长的字符串 \(T\),满足 \(T\) 是 \(S\) 的前缀,也是 \(S\) 的后缀,且 \(|T|<|S|\)。
对于一个字符串 \(S[1\cdots n]\),令 \(f[i]=|border(S[1\cdots i])|\)。
给定 \(n,k\) ,求若字符集无限的话,有多少不同的 \(f\) 数组满足至少有一个长度为 \(n\) 的串的 \(f\) 数组是它,且对于每个 \(i\in [1,n]\),有 \(0\leq f[i]\leq k\)。
答案对 \(10^9+7\) 取模。
数据范围
对于 \(30\%\),\(1\leq n\leq 5,0\leq k\leq 5\)
对于 \(50\%\),\(0\leq k\leq 7\)
另有 \(20\%\),\(k=1\)
对于 \(100\%\),\(1\leq n\leq 10^7,0\leq k\leq 10\)
solution
枚举长度从 1 到 n 递推方案数
f 数组等价于kmp算法中的next数组,匹配失败就会从 i 跳到 next[i]
题目中只要方案数即可,但为了保证f数组的正确性(f只能为最大值),还是要弄出每个位置的字符的一种方案
dp[i][j]表示前 i 位且 f[i] = j 的方案数,j 的范围为0——k,dp[i][j]若能转移到dp[i+1][p]需要满足条件:A.第 i + 1 位的字符与第 p 位相同,B.从 i 开始按照kmp流程匹配,第一个成功的位置为 p
按照上述方法转移即可
当 len < k 时每次转移不同,但事实上为了转移的正确性要暴力做到k + 1
暴力处理出每一种方案(每个位置的字符也要求出)有3700种
len > k + 1 时,因为只能和前 k 位匹配,而前 k 位已经固定,所以每次转移相同,写成矩阵转的形式快速幂加速转移
暴力枚举出翻案书3700种,矩乘复杂度k³log(n),总复杂度O(3700*k³log(n))
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步