博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ1355】【Baltic2009】Radio Transmission 详细证明【KMP】
阅读量:5031 次
发布时间:2019-06-12

本文共 929 字,大约阅读时间需要 3 分钟。

Description

【题目描述】

  给你一个字符串,它是由某个字符串不断自我连接形成的。 但是这个字符串是不确定的,现在只想知道它的最短长度是多少.

【输入】

  第一行给出字符串的长度,1 < L ≤ 1,000,000. 第二行给出一个字符串,全由小写字母组成.

【输出】

  输出最短的长度

  
题解
首先,我们对这个字符串求一遍nextnext数组,next[i]next[i]表示i的前缀和后缀的最长的相同的长度,即最长前缀后缀。答案就是nnext[n]n−next[n]。但是为什么呢?
证明
不妨设文本串为T,n=|T|n=|T|
这里写图片描述
下面我要证明Tnext[n]T−next[n]一定是字符串的循环节。
我们把next[n]next[n]TT这两个字符串对齐。
这里写图片描述
此时相同位置的字符是相同的。
这里写图片描述
显然,标红位置,即Tnext[n]T−next[n]next[n]next[n]的开头是相同的。
这里写图片描述
再可以把next[n]next[n]的标红部分对应回TT上面,又对应到next[n]next[n]上面。
这里写图片描述
我们可以像这样把TTnext[n]next[n]Tnext[n]T−next[n]填充满,所以Tnext[n]T−next[n]一定是字符串的循环节。
那为什么Tnext[n]T−next[n]一定是最短的呢?
因为如果存在比Tnext[n]T−next[n]更短的循环节,根据nextnext数组的定义,next[n]next[n]一定会加长。所以不存在比Tnext[n]T−next[n]更短的循环节。
因此Tnext[n]T−next[n]一定是T的最短循环节,nnext[n]n−next[n]就是这个循环节的长度。
代码:

#include
int n,next[1000005];char s[1000005];int main(){ scanf("%d%s",&n,s); next[0]=next[1]=0; for(int i=1;i

转载于:https://www.cnblogs.com/2016gdgzoi471/p/9476898.html

你可能感兴趣的文章
磁盘管理
查看>>
SAS学习经验总结分享:篇二—input语句
查看>>
UIImage与UIColor互转
查看>>
RotateAnimation详解
查看>>
系统管理玩玩Windows Azure
查看>>
c#匿名方法
查看>>
如何判断链表是否有环
查看>>
【小程序】缓存
查看>>
ssh无密码登陆屌丝指南
查看>>
MySQL锁之三:MySQL的共享锁与排它锁编码演示
查看>>
docker常用命令详解
查看>>
jQuery技巧大放送
查看>>
字符串转换成JSON的三种方式
查看>>
Hive时间函数笔记
查看>>
clojure-emacs-autocomplete
查看>>
一个自己写的判断2个相同对象的属性值差异的工具类
查看>>
10 华电内部文档搜索系统 search03
查看>>
[HIHO1149]回文字符序列(dp)
查看>>
[HDU1402]A * B Problem Plus(FFT)
查看>>
[CF803C] Maximal GCD(gcd,贪心,构造)
查看>>