Poj2406http: // poj.org/problem? Id = 2406
Given a string, the maximum number of identical substrings cannot be overlapped.
The next Array application of KMP. How can we determine whether such a substring exists and the number of substrings.
The next array is the position where the matching can continue when the matching fails. This requires that next [J] must be the maximum value that meets STR [1 .. next [J] = STR [J-next [J] + 1 .. J. If each prefix of a string is the maximum value that meets the conditions, the value of next [Len] is the end position of the previous substring.
For example, the value of ababab and next [4] is 2, that is, pointing to the first B, because STR [1 .. 2] = STR [3 .. 4]. Similarly, the value of next [6] is 4, so that STR [1 .. 2] = STR [3 .. 4] = STR [5 .. 6]. Obviously, AB is a substring that meets the condition.
If it is abababa, it is clear that no substrings meet the conditions except itself. And analyze its next array, next [7] = 5, next [5] = 3, next [3] = 1, that is, STR [2 .. 7] It can be composed of BA substring connections. How can this problem be solved? Very simple. If the substring meets the condition, Len % sublen must be 0. Sunlen can be obtained from the above analysis as len-next [Len].
(Here we can add an optimization. The output with the length of the prime number is 1, but the efficiency has not been increased by 0)
Because the substring is connected to the beginning and end, Len/sublen is the number of substr.
# Include <cstdio>
# Include <cstring>
Char STR [1000001];
Int next [1000001];
Int Len;
Void get_next () {// based on known next
Next [1] = 0;
Int J = 0;
For (INT I = 2; I <= Len; I ++ ){
While (j> 0 & STR [J + 1]! = STR [I])
J = next [J];
If (STR [J + 1] = STR [I]) J ++;
Next [I] = J;
}
}
Int main (){
While (scanf ("% s", STR + 1 )! = EOF ){
If (STR [1] = '.') break;
Len = strlen (STR + 1 );
Get_next ();
If (LEN % (LEN-next [Len]) = 0 ){
Printf ("% d \ n", Len/(LEN-next [Len]);
// For (INT I = 0; I <= Len; I ++)
// Printf ("% d", next [I]);
Continue;
}
Printf ("1 \ n ");
// For (INT I = 0; I <= Len; I ++)
// Printf ("% d", next [I]);
}
Return 0;
}
Poj1961http: // poj.org/problem? Id = 1961
1961 and 2406 are only one more enumeration step, and must be sublen> 1.
Code:
# Include <cstdio>
Char STR [1000001];
Int next [1000001];
Int Len;
Void get_next () {// based on known next
Next [1] = 0;
Int J = 0;
For (INT I = 2; I <= Len; I ++ ){
While (j> 0 & STR [J + 1]! = STR [I])
J = next [J];
If (STR [J + 1] = STR [I]) J ++;
Next [I] = J;
}
}
Int main (){
Int T = 0;
While (~ Scanf ("% d", & Len ){
Scanf ("% s", STR + 1 );
T ++;
Get_next ();
Printf ("Test Case # % d \ n", t );
For (INT I = 2; I <= Len; I ++ ){
If (next [I] & I % (I-next [I]) = 0) // K> 1, add next [I]! = 0 judgment
Printf ("% d \ n", I, I/(I-next [I]);
}
Printf ("\ n ");
}
}