KMP的next数组,对于next[i],是:1~i-1的最长的匹配的前缀和后缀的长度(也即在i位置匹配失败后,应该跳到的模式串的位置)
然后我们将所有满足要求的字串按照它的末尾位置分类。
1 #include <cstdio> 2 #include <cctype> 3 #define M 10007 4 #define maxn 200010 5 6 int n; 7 char aa[maxn]; 8 int f[maxn], dp[maxn]; 9 10 void gn( int &v ) { 11 char ch, opt; 12 while(!isdigit(ch=getchar())) opt=ch; 13 v=ch-'0'; 14 while( isdigit(ch=getchar())) v=v*10+ch-'0'; 15 if( opt=='-' ) v=-v; 16 } 17 void gc( char &ch ) { 18 while(!isalpha(ch=getchar())); 19 } 20 void getfail() { 21 f[0] = f[1] = 0; 22 for( int i=1,j; i<n; i++ ) { 23 j = f[i]; 24 while( j && aa[i]!=aa[j] ) j=f[j]; 25 f[i+1] = aa[i]==aa[j] ? j+1 : 0; 26 } 27 } 28 int main() { 29 int T; 30 gn(T); 31 while( T-- ) { 32 gn(n); 33 for( int i=0; i<n; i++ ) 34 gc(aa[i]); 35 getfail(); 36 int sum=0; 37 dp[0] = dp[1] = 0; 38 for( int i=2; i<=n; i++ ) { 39 dp[i] = dp[f[i]]+(f[i]!=0); 40 sum = (sum+dp[i])%M; 41 } 42 sum += n; 43 sum %= M; 44 printf( "%d ", sum ); 45 } 46 }