Power Strings Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 60872 Accepted: 25166 Description Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the empty string) and a^(n+1) = a*(a^n). Input Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case. Output For each s you should print the largest n such that s = a^n for some string a. Sample Input abcd aaaa ababab . Sample Output 1 4 3 Hint This problem has huge input, use scanf instead of cin to avoid time limit exceed. Source Waterloo local 2002.07.01
这道题就是求循环节的长度
也就是个nxt数组应用
答案就是n/(n-nxt[n]),注意n%(n-nxt[n])为真的时候要输出1
这个是为什么呢
动手画一画,nxt数组的特性就是这样,n-nxt[n]恰好就是一个循环节的长度
因为我是习惯全部+1来写,所以就很玄学
有一个最好要思考的细节
为什么是nxt[n+1],因为在n+1的时候才会失配(正常的KMP应该是0到len-1,然后nxt[len]是答案)
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 char a[1000000+100]; 6 int nxt[1000000+100],alen; 7 void getnxt() 8 { 9 int j=1,k=0; 10 nxt[1]=0; 11 while(j<=alen) 12 { 13 if(k==0||a[j]==a[k]) 14 j++,k++,nxt[j]=k; 15 else 16 k=nxt[k]; 17 } 18 } 19 int main() 20 { 21 while(1) 22 { 23 memset(nxt,0,sizeof(nxt)); 24 scanf("%s",a+1); 25 if(a[1]=='.')return 0; 26 alen=strlen(a+1); 27 getnxt(); 28 if(alen%(alen+1-nxt[alen+1]))puts("1"); 29 else printf("%d ",(alen)/((alen+1)-nxt[alen+1])); 30 } 31 return 0; 32 }