kmp。
字符串的题都好难啊。
进行一次kmp,用一个dp[i]数组记录前缀中前缀匹配后缀的数量(算本身)
同时进行一个类似kmp的过程,用变量k表示满足长度限制后,最长的匹配前缀和后缀。
则num[i]=dp[k]。为什么呢?
首先变量k满足了长度限制,dp数组记录了匹配串的数量。dp多的1正好可以充当目前的前缀和后缀。
字符串的题都好难啊。。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long LL; const int maxn = 1000000 + 10; const LL mod = 1000000007; char a[maxn]; int next[maxn]; LL dp[maxn],res; int T,n,j,k; int main() { //freopen("ex_zoo2.in","r",stdin); scanf("%d",&T); while(T--) { scanf("%s",a+1); n=strlen(a+1); res=1; memset(next,0,sizeof(next)); memset(dp,0,sizeof(dp)); j=k=0; dp[1]=1; for(int i=1;i<n;i++) { while(a[i+1]!=a[j+1] && j) j=next[j]; if(a[i+1]==a[j+1]) j++; next[i+1]=j; dp[i+1]=dp[j]+1; while(k && a[i+1]!=a[k+1]) k=next[k]; if(a[i+1]==a[k+1]) k++; while(k>(i+1)/2) k=next[k]; res*=(dp[k]+1); res%=mod; } for(int i=1;i<=n;i++) printf("%d %d ",next[i],dp[i]); printf("%lld ",res); } return 0; }