题目链接

观察题目,我们发现直接计算是困难的,先构造单个合法的 \(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)\)。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 3005
#define mod 998244353
#define ll long long
using namespace std;
char s[N];
ll nex[N],maxpos[N],ch[N][27],f[N][N];
int main(){
ll m;cin>>m;cin>>(s+1);ll n=strlen(s+1);
ll sum=1;
for(ll i=1;i<=m;i++)sum=(sum*26)%mod;
for(ll i=2,j=0;i<=n;i++){
while(j && s[i]!=s[j+1])j=nex[j];
if(s[i]==s[j+1])j++;
nex[i]=j;
}
for(ll i=0;i<=n;i++){
for(ll j=1;j<=26;j++){
if(s[i+1]-'a'+1==j)ch[i][j]=i+1;
else ch[i][j]=ch[nex[i]][j];
if(ch[i][j])maxpos[i]=j;
}
}
f[0][0]=1;
for(ll j=0;j<=m;j++){
for(ll i=0;i<=n;i++){
for(ll k=maxpos[i];k<=26;k++)f[ch[i][k]][j+1]=(f[ch[i][k]][j+1]+f[i][j])%mod;
}
}
ll ans=0;
for(ll i=0;i<=n;i++){
ll now=i;
for(ll j=1;j<=m;j++){
ans=(ans*1ll+(26-maxpos[now])*1ll*f[i][m-j])%mod;
now=ch[now][maxpos[now]];
if(!now)break;
}
if(now==i)ans=(ans+1)%mod;
}
cout<<(((sum-ans)%mod)+mod)%mod;
}

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. 分享一个Java功能小案例(代码已开源哦)

    工程合集 工程列表 地址预览 B站 抖音

  2. 刷了一个月AI歌唱的视频 做一个大胆预测

    现在的AI热点转到ChatAI和AI唱歌去了 很好理解(现在每天在看Neuro的切片 感慨这才是看V的初心 可惜Neuro这个形象在创立的时候只是一个ChatAI 和游戏用的GameBOT并不是同一个 ...

  3. 使用npm下载vue

    一.安装npm 1. 安装node.js npm(Node Package Manager): node.js下的包管理器 前往node.js官网下载并安装工具,nodejs安装完毕后自动会安装npm ...

  4. zabbix 主动模式下报文分析

    获取监控项列表 客户端发起请求 3次握手之后,请求监控项列表: {"request":"active checks","host":&quo ...

  5. 王道oj/problem23

    网址:oj.lgwenda.problem/23 代码: #define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include<stri ...

  6. python-gitlab 一个简单demo

    背景 需要收集git仓库信息到数据库供前端展示 包括:仓库信息.仓库所有者.成员列表.提交信息.活跃情况等 需要定时启动.灵活触发 实现简介 使用gitlab v4 restful 接口 使用pyth ...

  7. 批量获取FreeSWITCH所有分机号及其密码

    前言 有次项目上需要获取所有FreeSWITCH注册分机的分机号和密码,就用python写了个小脚本来获取. 可以先把freeswitch/conf/directory/default/目录下的所有x ...

  8. 基于redis6搭建集群

    前言 系统版本:CentOS 7 redis版本:redis6.2.4,官方tar.gz包 两台服务器: 172.50.11.11 端口7002.7004.7006 172.50.12.11 端口70 ...

  9. Stack Overflow开发者调查发布:AI将如何协助DevOps

    Stack Overflow 发布了开创性的2023年度开发人员调查报告 [1].报告对 90,000 多名开发人员进行了调查,全面展示了当前软件开发人员的体验.接下来,本文将重点介绍几项重要发现,即 ...

  10. firefox对webview性能数据监控的模拟

    现在为了降低手机端的开发成本,越来越多的手机应用采用html5在进行开发,这样可以保证一处开发,到处嵌入. 但是这样的手机性能经常会是个瓶颈,因为当体验要求变高时,大多依赖html渲染引擎来对dom数 ...