在 i 和 nexti 之间连一条边,可以得到一棵以 0 为根的树。
建出来树结构,如果没有 |Si| × 2 ≤ i 的限制,答案就是每一个节点
的深度。
这个idea很不错啊
下面是早期的代码 没有建树 但也是线性的
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define M 1000000007
typedef long long ll;
using namespace std;
int n;
char S[1000005];
int next[1000005],cnt[1000005];
int main()
{
int Q;
scanf("%d",&Q);
while (Q--)
{
while (getchar()!='\n');
scanf("%s",S+1);
n=strlen(S+1);
int k=0;
next[1]=0; cnt[1]=1;
for (int i=2;i<=n;i++)
{
while (k && S[k+1]!=S[i]) k=next[k];
if (S[k+1]==S[i]) k++;
next[i]=k;
cnt[i]=cnt[k]+1;
}
ll ans=1;
k=0;
for (int i=2;i<=n;i++)
{
while (k && S[k+1]!=S[i]) k=next[k];
if (S[k+1]==S[i]) k++;
while (2*k>i) k=next[k];
ans=(ans*(cnt[k]+1))%M;
}
cout<<ans<<endl;
}
return 0;
}