将原串看成是循环节的后缀加上若干个循环节,那么考虑每种情况都会发现n-next[n]就是最小循环节。(一开始总输出n。。。然后发现build_next连调用都没有,%%%
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define REP(i,s,t) for(int i=s;i<=t;i++) const int nmax=1000005; char s[nmax]; int next[nmax],len; void build_next(){ next[0]=next[1]=0; REP(i,1,len-1){ int t=next[i]; while(t&&s[t]!=s[i]) t=next[t]; next[i+1]= s[t]==s[i]? t+1: 0; } } int main(){ scanf("%d%s",&len,s); build_next(); printf("%d ",len-next[len]); return 0; }
1355: [Baltic2009]Radio Transmission
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 694 Solved: 465
[Submit][Status][Discuss]
Description
给你一个字符串,它是由某个字符串不断自我连接形成的。 但是这个字符串是不确定的,现在只想知道它的最短长度是多少.
Input
第一行给出字符串的长度,1 < L ≤ 1,000,000. 第二行给出一个字符串,全由小写字母组成.
Output
输出最短的长度
Sample Input
8
cabcabca
cabcabca
Sample Output
3
HINT
对于样例,我们可以利用"abc"不断自我连接得到"abcabcabc",读入的cabcabca,是它的子串