题目描述
给你一个字符串,它是由某个字符串不断自我连接形成的。
但是这个字符串是不确定的,现在只想知道它的最短长度是多少.
题解
这是一道结论题:
那么怎么证明呢??
我们把文本T与next[n] 取出来并且开头对齐,如图:
此时相同位置的字符是相同的。
因为题目告诉我们文本串是由一个某个字符串不断自我连接形成的。
那么
和
的开头是一样的
将所对应的回到文本T上去,在回到next上,这样反复对应,我们发现
和
可以用
填充满,所以
一定是文本串的循环节。
那么如何证明
是最短的循环节呢,我们回忆一下next数组的定义,如果存在比
更短的循环节的话,next会更长,所以
是最短的。
代码:
//By Bibi
/// .-~~~~~~~~~-._ _.-~~~~~~~~~-.
/// __.' ~. .~ `.__
/// .'// \./ \\`.
/// .'// | \\`.
/// .'// .-~"""""""~~~~-._ | _,-~~~~"""""""~-. \\`.
/// .'//.-" `-. | .-' "-.\\`.
/// .'//______.============-.. \ | / ..-============.______\\`.
/// .'______________________________\|/______________________________`.
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define dep(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
const int MAXN=1000010;
int len;
int next[MAXN];
int read(){
int sum=0,flag=1;
char c;
for(;c<'0'||c>'9';c=getchar())if(c=='-') flag=-1;
for(;c>='0'&&c<='9';c=getchar())sum=(sum<<1)+(sum<<3)+c-'0';
return sum*flag;
}
int n;
char s[MAXN];
void init(){
n=read();
scanf("%s",s+1);
len=strlen(s+1);
}
void yuchuli(){
int j=0;
next[1]=0;
rep(i,2,len){
while(j&&s[i]!=s[j+1]) j=next[j];
if(s[i]==s[j+1]) ++j;
next[i]=j;
}
}
int main(){
init();
yuchuli();
printf("%d",n-next[n]);
return 0;
}