这道题要求的是所有类型前缀的与整个字符串匹配出的个数之和
那么所以每个可以先从头开始,把每个前缀先算进去,然后利用next数组的性质,也就是当前pre[i-1]==suffix[i-k]
所以我们可以对应每个i找到从它开始的最大的串和一个前缀完全匹配
那么i就可以贡献出这个前缀长度的个数,因为前缀中从[1-len]都可以匹配到一个新的串
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define MAX 200007
#define MOD 10007
using namespace std;
void get_next ( char p[] , int next[] )
{
int i = 0 , k = -1 , len = strlen(p);
next[0] = -1;
while ( i < len )
if ( k == -1 || p[i] == p[k] )
i++,k++,next[i] = k;
else k = next[k];
}
int pre[MAX];
int sum[MAX];
int solve ( char s[] , int n )
{
int next[MAX];
get_next ( s , next );
/*cout << "_________next__________________" << endl;
for ( int i = 0 ; i <= n ; i++ )
cout << next[i] << " " ;
cout << endl;
cout << "_______________________________" << endl;*/
memset ( pre , 0 , sizeof ( pre ) );
memset ( sum , 0 , sizeof ( sum ) );
for ( int i = 1 ; i <= n ; i++ )
pre[i-next[i]] = max ( next[i] , pre[i-next[i]] );
/*cout << "_________pre____________________" << endl;
for ( int i = 0 ; i <= n ; i++ )
cout << pre[i] << endl;
cout << "________________________________" << endl;*/
int ans = n;
for ( int i = 1 ; i < n ; i++ )
ans = ( ans + pre[i] )%MOD;
return ans;
}
int t,n;
char s[MAX];
int main ( )
{
scanf ( "%d" , &t );
while ( t-- )
{
scanf ( "%d" , &n );
scanf ( "%s" , s );
printf ( "%d\n" , solve ( s , n ) );
}
}