给你一个字符串 s_1s1,它是由某个字符串 s_2s2 不断自我连接形成的。但是字符串 s_2s2 是不确定的,现在只想知道它的最短长度是多少。
输入格式
第一行一个整数 LL,表示给出字符串的长度。
第二行给出字符串 s_1s1 的一个子串,全由小写字母组成。
输出格式
仅一行,表示 s_2s2 的最短长度。
输入输出样例
输入 #1复制
8 cabcabca
输出 #1复制
3
说明/提示
样例输入输出 1 解释
对于样例,我们可以利用 \texttt{abc}abc 不断自我连接得到 \texttt{abcabcabc}abcabcabc,读入的 \texttt{cabcabca}cabcabca,是它的子串。
规模与约定
对于全部的测试点,保证 1 < L \le 10^61<L≤106。
这个题,就是需要找到其中的规律,即n与next【n】之间的关系,就从题目所给的样例来说明一下,题中所给的cabcabca,先求出其中的next【n】为0 0 0 1 2 3 4 5不难得出它的next数组为这个,而求数组的值的方法也有许多,直接求出来就好了,然后观察,因为已知它的最小长度为3了所以的话也也已知了数组长度为8最后一位的next值也知道,所以说最小长度=n-next【n】因为最短的字符串的next的值在模板串中都是0,所以前x个数的next的值都是0,所以next【x+1】=1,所一就可得出next【n+x】=n,所以x=n-next【n】。
#include<stdio.h>
int n,a[1000000];
char s[1000000];
int main()
{
scanf("%d%s",&n,s+1);
int j=0;
for(int i=2;i<=n;i++)
{
while(j&&s[i]!=s[j+1]) j=a[j];
if(s[i]==s[j+1]) j++;
a[i]=j;
}
printf("%d",n-a[n]);
return 0;
}