hdu 3336

 

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\n", sum );
45     }
46 }
View Code

 

posted @ 2015-03-10 21:40  idy002  阅读(144)  评论(0编辑  收藏  举报