题目链接

观察题目,我们发现直接计算是困难的,先构造单个合法的 \(T\) 分析其性质。

为了构造出 \(T\),先考虑构造时 \(T\) 时什么时候会出现不合法的情况,此时 \(T\) 会有一段和 \(S\) 相同的前缀,且这段前缀后面跟着的字符比 \(S\) 所跟的小。

为了避免这种情况出现,我们需要在每次添加字符时进行检查,具体而言,我们需要保证当前字符串的任意一个为 \(S\) 前缀的后缀在 \(S\) 中的下一个字符小于等于当前的字符。

这个约束条件显然与 KMP 有点关联,我们边加字符边维护当前字符串的一个最长的为 \(S\) 前缀的后缀,相当于建出 \(S\) 的 KMP 自动机,维护当前所在节点,每次直接跳向上的转移边查找约束后即可合法构造。

接下来考虑 \(T\) 开始循环后在自动机上会怎样转移,考察在输入无穷次 \(T\) 后走到的一个节点,由于 KMP 自动机的节点主要代表当前字符串与 \(S\) 的一个前缀相同的最大后缀的长度,且输入的长度无穷大,因此如果我们再输入一次 \(T\),此串与 \(S\) 的一个前缀相同的最大后缀的长度不改变,即还会回到原本的节点,故此过程构成了一个环,直接硬 dp \(m\) 次找环的个数可以做到 \(O(n^2m)\)。

如何优化呢?考察我们 dp 找环时每次转移往待定 \(T\) 的末尾添加字符,先找到我能放置的最小的字符,即待定 \(T\) 与 \(S\) 的一个前缀相同的所有后缀中下一个字符最大的那个,如果更小就不合法,要么添加此字符要么再添加更大的。

如果添加此字符,则继续往下转移,否则因为 \(S\) 中没有对应的前缀,我们会回到根节点。

故此过程对于以每个节点为起点的环,不过根节点的环最多只有一个(沿唯一的路径一直走,因此我们可以暴力判断存不存在此环,并枚举走到根节点的最小时间,在此时间之前我们沿着既定路线走,之后跳到根节点再走回来,走回来的方案数可以 dp 预处理,设 \(f_{i,j}\) 表示到达第 \(i\) 个节点走了 \(j\) 步的方案数,转移是容易的。

两个部分综合起来时间复杂度 \(O(nm)\)。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #define N 3005
  6. #define mod 998244353
  7. #define ll long long
  8. using namespace std;
  9. char s[N];
  10. ll nex[N],maxpos[N],ch[N][27],f[N][N];
  11. int main(){
  12. ll m;cin>>m;cin>>(s+1);ll n=strlen(s+1);
  13. ll sum=1;
  14. for(ll i=1;i<=m;i++)sum=(sum*26)%mod;
  15. for(ll i=2,j=0;i<=n;i++){
  16. while(j && s[i]!=s[j+1])j=nex[j];
  17. if(s[i]==s[j+1])j++;
  18. nex[i]=j;
  19. }
  20. for(ll i=0;i<=n;i++){
  21. for(ll j=1;j<=26;j++){
  22. if(s[i+1]-'a'+1==j)ch[i][j]=i+1;
  23. else ch[i][j]=ch[nex[i]][j];
  24. if(ch[i][j])maxpos[i]=j;
  25. }
  26. }
  27. f[0][0]=1;
  28. for(ll j=0;j<=m;j++){
  29. for(ll i=0;i<=n;i++){
  30. for(ll k=maxpos[i];k<=26;k++)f[ch[i][k]][j+1]=(f[ch[i][k]][j+1]+f[i][j])%mod;
  31. }
  32. }
  33. ll ans=0;
  34. for(ll i=0;i<=n;i++){
  35. ll now=i;
  36. for(ll j=1;j<=m;j++){
  37. ans=(ans*1ll+(26-maxpos[now])*1ll*f[i][m-j])%mod;
  38. now=ch[now][maxpos[now]];
  39. if(!now)break;
  40. }
  41. if(now==i)ans=(ans+1)%mod;
  42. }
  43. cout<<(((sum-ans)%mod)+mod)%mod;
  44. }

P5404 [CTS2019] 重复 题解的更多相关文章

  1. LOJ3123 CTS2019 重复 KMP自动机、DP、多项式求逆

    传送门 CTS的计数题更完辣(撒花 Orz zx2003,下面的内容在上面的博客基础上进行一定的补充. 考虑计算无限循环之后不存在子串比\(s\)字典序小的串的个数.先对串\(s\)建立KMP自动机, ...

  2. UVALive 5881 Unique Encryption Keys (DP)

    Unique Encryption Keys 题目链接: http://acm.hust.edu.cn/vjudge/problem/26633 Description http://7xjob4.c ...

  3. AC自动机模板2(【CJOJ1435】)

    题面 Description 对,这就是裸的AC自动机. 要求:在规定时间内统计出模版字符串在文本中出现的次数. Input 第一行:模版字符串的个数N. 第2->N+1行:N个字符串.(每个模 ...

  4. hdu1686字符串kmp

    The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e ...

  5. 10.15 lzxkj

    几天前写的,忘了放了,在此填坑 10月16的题我出的不写题解了 lzxkj 题目背景 众所不周知的是, 酒店之王 xkj 一个经常迷失自我的人 有一天, 当起床铃再一次打响的时候, TA 用 O(1) ...

  6. 【BZOJ3992】[SDOI2015]序列统计 NTT+多项式快速幂

    [BZOJ3992][SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属 ...

  7. 【题解】CTS2019珍珠(二项式反演+卷积)

    [题解]CTS2019珍珠 题目就是要满足这样一个条件\(c_i\)代表出现次数 \[ \sum {[\dfrac {c_i } 2]} \ge 2m \] 显然\(\sum c_i=n\)所以,而且 ...

  8. 最长重复字符串题解 golang

    最长重复字符串题解 package main import ( "fmt" "strings" ) type Index map[int]int type Co ...

  9. 【LeetCode题解】3_无重复字符的最长子串(Longest-Substring-Without-Repeating-Characters)

    目录 描述 解法一:暴力枚举法(Time Limit Exceeded) 思路 Java 实现 Python 实现 复杂度分析 解法二:滑动窗口(双指针) 思路 Java 实现 Python 实现 复 ...

  10. 力扣(LeetCode)删除排序链表中的重复元素II 个人题解

    给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字. 思路和上一题类似(参考 力扣(LeetCode)删除排序链表中的重复元素 个人题解)) 只不过这里需要用到一个前 ...

随机推荐

  1. Elasticsearch日常开发

    2020-08-12 14:51:37 每次遇到ES开发,一般都是查询es里面的数据,今天我教大家一个简单的es的查询.废话不多说,直接上代码. 在pom文件中引入 <dependency> ...

  2. 机试练习(一)——Codeforces 784B Santa Claus and Keyboard Check

    最近在准备机试,对练习的机试题做个总结.之前没有学过C++,只学过C语言,但是实际用起来的时候发现C++是更适合机试的语言,因为它的库函数更多,能支持更多操作,将一些代码简化. 习惯了C语言定义字符串 ...

  3. matlab gui .mat数据读取

    在matlab的gui中用load函数读取.mat等类型数据 %定义全局变量 global img_correct %读取数据名称及位置 [filename,pathname]=uigetfile({ ...

  4. Oracle备份与还原(实用版)

    Oracle备份与还原 EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用. EXPDP和IMPDP是服务端的工具程序,他们只能在ORACLE服务端使用,不能在客户端使用. I ...

  5. KVM 虚拟机 热插拔硬盘

    新建硬盘 lvm 命令 lvcreate -L 200G -n lv02 ssd01 qemu-img 命令 qemu-img create -f raw test1G.raw 1G dd 命令 dd ...

  6. 分布式ID性能评测:CosId VS 美团 Leaf

    分布式ID性能评测:CosId VS 美团 Leaf 基准测试环境 MacBook Pro (M1) JDK 17 JMH 1.36 运行在本机的Docker 的 mariadb:10.6.4 运行基 ...

  7. node: #!/usr/bin/env node

    声明 windows中不支持Shebang,它是通过文件的扩展名来确定使用什么解释器来执行脚本 参考链接: https://juejin.cn/post/6844903826344902670

  8. 【青少年CTF】Crypto-easy 题解小集合

    Crypto-easy 1.BASE 拿到附件用cyberchef自动解码得到flag 2.basic-crypto 拿到附件发现是一串01的数字,这时候想到二进制转换 然后base64在线解码 接着 ...

  9. Redis从入门到放弃(10):分布式锁

    在分布式系统中,实现对共享资源的安全访问是一个关键问题.Redis作为一种高性能的内存数据库,提供了多种方式来实现分布式锁,以解决多个节点之间对共享资源的并发访问问题. 本文将介绍五种Redis分布式 ...

  10. 国标GB28181视频平台EasyGBS视频监控平台无法播放,抓包返回ICMP排查过程

    国标GB28181视频平台EasyGBS是基于国标GB/T28181协议的行业内安防视频流媒体能力平台,可实现的视频功能包括:实时监控直播.录像.检索与回看.语音对讲.云存储.告警.平台级联等功能.国 ...