题意:给定字符串 ,计数 "串 的长度" 可能的种数有多少种,使得 能被 作为印章印出来,且 。,。
第一步:
求出 的周期 ,包含 ()。转化为求 的情况下, 的取值有多少种,要求 。记 。
第二步:
的形式,考虑同余最短路。(当题目中出现类似 "若干个数求和" 的形式,可以考虑同余最短路)
记 ,令 表示 的所有数中,能表示为 的最小数是多少。
如果这里直接跑最短路,一共有 个点,每个点通过 都会连出 条边,所以复杂度至少是 的。同时可以构造出来 ,使得周期数量达到 个,同时周期的长度都是 的,肯定能被卡。
第三步:
我们需要改进这个方法。根据 border 理论, 可以被分成 个等差数列。
把每个等差数列单独拎出来,依次考虑。
考虑第 个等差数列 ,构造 个点编号 。 表示如果使用前 个等差数列中的数,它们能组成的数中, 的最小数是多少。
我们要用 推出 :使用前 个等差数列中的数,它们能组成的数中, 的最小数是多少。
首先把同余最短路的图建出来。观察发现,按照 分类,每一类之间没有边,内部有边。于是我们把 相等的一起处理。
也就是说,比如 ,先把 转移到 ,然后再转移 和 ,各自求解,然后拼出来 。
如果还是把 相等的点拿出来跑最短路,还是没有优化。这里有一个破环为链的 DP 想法。举个例子,比如当前等差数列是 ,,所以按 的余数分类。比如现在正在处理 。它们之间的边连出来应该是这样:

不妨 是其中最小的点。我们以 这个点破环为链:只保留从前往后的边(不越界)。我们会证明,在这个链图上如果跑最短路,答案和环图是一样的。

证明:考虑到点 的最短路,假设破环为链的起点是 。如果存在另一个点 ,走了一条不存在的边使得 更短了。但是因为 是 最小的,所以 ;同时因为 走到 是越界的,所以 到 一定比 到 更远,根据等差数列的性质, 一定存在一条比 的边更短的。因为 ,而且 出发还有更小的边,所以一定不会存在这样的 。

因此我们只需要保留这个链图跑最短路。但是真的需要跑最短路吗?是可以优化的。
记链上第 个点的 值为 (从 开始编号)。首先可以写出一个朴素的 DP 方程。
。这里 的 是上面 的 。
这个式子很显然可以单调队列优化,于是复杂度从最短路和边数有关的复杂度,降低到 。
这一部分贡献的复杂度,对于每个等差数列会贡献 的复杂度,一共 个等差数列,所以会贡献 的复杂度。
第四步:
第三步解决了从 的问题,但是我们还需要让 的模数变成第 个等差数列的 ,而不是第 个等差数列的 。例如当前模数(首项) ,下一个等差数列模数(首项) 。怎么把 的定义从 的最小数,转化为 的最小数,从而更方便用 的 推出属于 的 ?
把 的 记作 , 的 记作 。新的模数记作 。
这里 的更新取值分两种。
借一个具体的例子,比如 。
第一种:因为 ,所以我们知道 可以取到 。也就是如果 ,那 。
第二种:在 里 因为 ,所以 都可以取到。在 里对应着我们会用 去更新 。
考虑 的更新建成同余最短路的图,实际上每个点只向后方第 个点连边。

理解一下。这里 的同余最短路的建图和第三步的建图是不同的—— 只有一种边,就是向后走 步的边。而第三步的建图有 一共 种向后走的边。所以 的建图实际上就是一个环。
顺理成章地,沿用上面破环为链的想法。找到 的所有 里最小的,记作 。以 号点为起点破环为链,得到一条 的链,然后在这条链上走一遍,也就是 。
切换一次模数的复杂度是 的。一共切换 次,也是 。
总共 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!