题目

给出一个长度为\(n\)的串\(s\),询问有多少个长度为\(m\)的串\(t\) 

满足 \(t\) 的无限循环串存在一个长度为\(n\)且比\(s\)字典序严格小的子串

$ n , m \le 2000 $

题解

  • 自从CTS打铁之后就非常自闭,智商一天不如一天,所以感觉这题异常抽象。。。

    我看的这位神仙的题解

  • Part 1

    考虑统计任意字串都大于等于的数量然后减去,首先对 $ s $ 建立 $ kmp $ 自动机

    由于题目中的限制,结点 $ i $ 的出边不能比 $ i+1,nxt[i]+1,nxt[nxt[i]]+1,\cdots $ 位字符(\(fail\)链上的后一位)小

    只要能在这样的自动机上走无限多次 \(t\) ,那么串 \(t\) 就是合法的

    考虑状态\((i,j)\)表示自动机在结点\(i\)时,构造到了 \(t\) 的对应第\(j\)位

    不同\((i,j)\)的数量也是有限的,那么一旦第二次到某个 $ (i,j) $ 的时候就出现了循环节

    考虑循环节的长度为\(l\) ,显然有 \(l\) 要么是\(|s|\) 的倍数(1),要么是\(|s|\)的因数(2)

    到达\((i,j)\)的最后一次一定是失配的,否则可以把循环节的起点向前移动

    从 \(i\) 开头的是 \(t\) 的一个循环位移 \(t'\) , 现在如果是情况(1),设循环节为\(kt’(k>1)\),说明\(s_{1,i} + kt'\)有一个更小的循环节\(t’\),那么显然有一个更小的循环节长度为 \(|t'|\)

    所以在有限步会走到一个环,且\(l\)满足(2),那就在环里不出来了=O^O=

    所以一个串一定可以映射到一个环

  • Part 2

    进一步考虑题目中的限制,相当于只有最小的那条边可能连向某个非0位置,其它的边一定连向0

    记这两种边为实边和虚边,如果\(i\)的实边不连向\(i+1\),那么 \(i+1\) 到 \(n\) 就都不连通,没用了

    所以自动机类似这样一个\(\rho\)形

  • Part 3

    • 分开计数,考虑单独末尾的环

      如果长度为\(m\)的因数那么就可以贡献长度个不同的串,否则不贡献答案

    • 考虑经过0的环

      最后的环一定是所有环在0的组合

      一种顺序的环贡献就是最后一个环的长度,可以枚举一个最后一个环上的点

      \(f_{i,j}\)表示从 \(0\) 走 \(i\) 步到 \(j\) 的方案,\(g_{i,j}\) 表示从 \(j\) 经 \(i\) 步沿黑边跳回 \(0\) 的方案

      所以 \(ans \ = \ \sum _{i=0}^{m} \sum_{j=0}^{n} f_{i,j} \times g_{m-i,j}\)

  • 暂时不会$n\ log n $的多项式解法

#include<bits/stdc++.h>
#define ll long long
#define mod 998244353
using namespace std;
const int N=2010;
int n,m,nxt[N],to[N],mx[N],f[N][N],g[N][N],len,pw=1;
char s[N];
void inc(int&x,int y){x+=y;if(x>=mod)x-=mod;}
int main(){
// freopen("repeat.in","r",stdin);
// freopen("repeat.out","w",stdout);
scanf("%d%s",&m,s+1);n=strlen(s+1);
for(int i=1;i<=m;++i)pw=(ll)pw*26%mod;
for(int i=2,j=0;i<=n;nxt[i++]=j){
while(j&&s[i]!=s[j+1])j=nxt[j];
if(s[i]==s[j+1])++j;
}
for(int i=0;i<=n;++i){
int k=i==n?nxt[i]:i;
mx[i]=s[to[i]=k+1]-'a';
while(k){
k=nxt[k];
if(mx[i]<s[k+1]-'a')mx[i]=s[to[i]=k+1]-'a';
}
if(to[i]!=i+1)len=i-to[n=i]+1;
}
f[0][0]=1;
for(int i=1;i<=m;++i)
for(int j=0;j<=n;++j){
inc(f[i][to[j]],f[i-1][j]);
inc(f[i][0],(ll)(25-mx[j])*f[i-1][j]%mod);
}
for(int i=0;i<=n;++i)g[1][i]=25-mx[i];
for(int i=2;i<=m;++i)
for(int j=0;j<=n;++j)g[i][j]=g[i-1][to[j]];
int ans=!(m%len)?len:0;
for(int i=0;i<=m;++i)
for(int j=0;j<=n;++j)inc(ans,(ll)f[i][j]*g[m-i][j]%mod);
cout<<(pw-ans+mod)%mod<<endl;
return 0;
}

【loj3123】【CTS2019】重复的更多相关文章

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

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

  2. [LOJ3123] CTSC2019重复

    Description 给定一个⻓为 n 的字符串 s , 问有多少个⻓为 m 的字符串 t 满足: 将 t 无限重复后,可以从中截出一个⻓度为 n 且字典序比 s 小的串. m ≤ 2000 n ≤ ...

  3. 【LOJ】#3123. 「CTS2019 | CTSC2019」重复

    LOJ3123 60pts 正难则反,熟练转成总方案数减掉每个片段都大于等于s的字典序的方案 按照一般的套路建出kmp上每个点加一个字符的转移边的图(注意这个图开始字母必须是nxt链中下一个相邻的字符 ...

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

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

  5. 题解-CTS2019 珍珠

    题面 CTS2019 珍珠 有 \(n\) 个在 \([1,d]\) 内的整数,求使可以拿出 \(2m\) 个整数凑成 \(m\) 个相等的整数对的方案数. 数据范围:\(0\le m\le 10^9 ...

  6. 避免重复造轮子的UI自动化测试框架开发

    一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...

  7. 【SQLServer】记一次数据迁移-标识重复的简单处理

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 今天在数据迁移的时候因为手贱遇到一个坑爹问题,发来大家乐乐,也传授新手点经验 迁移惯用就 ...

  8. 12、Struts2表单重复提交

    什么是表单重复提交 表单的重复提交: 若刷新表单页面, 再提交表单不算重复提交. 在不刷新表单页面的前提下: 多次点击提交按钮 已经提交成功, 按 "回退" 之后, 再点击 &qu ...

  9. 关于Android避免按钮重复点击事件

    最近测试人员测试我们的APP的时候,喜欢快速点击某个按钮,出现一个页面出现多次,测试人员能不能禁止这样.我自己点击了几下,确实存在这个问题,也感觉用户体验不太好.于是乎后来我搜了下加一个方法放在我们U ...

随机推荐

  1. Redis 多级缓存架构和数据库与缓存双写不一致问题

    采用三级缓存:nginx本地缓存+redis分布式缓存+tomcat堆缓存的多级缓存架构 时效性要求非常高的数据:库存 一般来说,显示的库存,都是时效性要求会相对高一些,因为随着商品的不断的交易,库存 ...

  2. Linux 6 修改ssh默认远程端口号

    linux 默认的ssh远程端口是22,有时默认端口会遭到别有用心的人们扫描或攻击,为了时我们的系统更加安全那就需要修改远程端口号 操作步骤:1.修改ssh_config配置文件 vim /etc/s ...

  3. java之hibernate之加载策略和抓取策略

    1.加载策略:指hibernate查询数据时,采用什么样的方式将数据写入内存.Hibernate中提供了两种方式来加载数据:懒加载和即时加载. 2.懒加载又称延迟加载,指使用hiberante API ...

  4. kube-state-metrics 详解

    原文:https://mp.weixin.qq.com/s/176eyFBknzdA5wpiJrxDSg 概述 已经有了 cadvisor.heapster.metric-server,几乎容器运行的 ...

  5. Excel工作表密码保护的破解

    操作步骤:打开Visual Basic编辑器,单击“插入-->模块“,将以下代码粘贴到模块中即可. Sub DelPassword() ActiveSheet.Protect DrawingOb ...

  6. Hybris产品主数据的价格折扣维护

    登录Hybris backoffice的产品管理界面,进入price标签页,点击Create new Discount Row按钮: 在Discount下拉地段里选择10%的折扣,这个产品原来的单价是 ...

  7. 如何去除有道云笔记广告(windows)

    一.适用于6.0之前版本 你只需要:找到有道云笔记的安装路径,*\Youdao\YoudaoNote\theme\build.xml 用笔记本打开这个文件,找到'左下角广告'这几个字,把下面的代码删掉 ...

  8. sqlserver数据,将一行某一列字符串的值用“_”分割分别填充到这一行的其他列

    分割字符到列DECLARE @a VARCHAR(10)SET @a ='00G-2-1102'SELECT CHARINDEX('-',@a,CHARINDEX('-',@a))SELECT CHA ...

  9. Python学习日记(二十六) 封装和几个装饰器函数

    封装 广义上的封装,它其实是一种面向对象的思想,它能够保护代码;狭义上的封装是面向对象三大特性之一,能把属性和方法都藏起来不让人看见 私有属性 私有属性表示方式即在一个属性名前加上两个双下划线 cla ...

  10. 03-JavaScript语法介绍

    本篇主要关于原生JavaScript的介绍,其中包括其嵌入HTML页面方式,JavaScript的语法结构,以及贪吃蛇案例: 一.绪论 JavaScript是运行在浏览器端的脚步语言,JavaScri ...