50分做法,暴力枚举nest(稍微带点记忆化)
如下:
#include<bits/stdc++.h>
using namespace std;
string t;
long long len,ans=1,n;
long long nest[1000006];
long long he[1000006];
void q_nest()
{
long long k=0;
for(long long i=2;i<=len;i++)
{
while(k>0&&t[k+1]!=t[i])
k=nest[k];
if(t[k+1]==t[i])
k++;
nest[i]=k;
}
for(long long i=1;i<=len;i++)
he[i]=he[nest[i]]+1;
}
int main()
{
cin>>n;
while(n--)
{
ans=1;
cin>>t;
len=t.length();
t=' '+t;
q_nest();
for(long long i=1;i<=len;i++)
{
for(long long j=i;j;j=nest[j])
if(nest[j]*2<=i)
{
ans=(ans*he[j])%1000000007;
break;
}
}
cout<<ans<<endl;
}
return 0;
}
70分做法(其他oj满分比如luogu,可能是ACWing测评鸡太水辣)
把暴力枚举换成倍增(倍增就不多说辣)
如下
#include<bits/stdc++.h>
using namespace std;
char t[1000006];
int len,ans=1,n,m;
int nest[25][1000006];
int he[1000006];
void q_nest() {
int k=0;
for(int i=2; i<=len; i++) {
while(k>0&&t[k+1]!=t[i])
k=nest[0][k];
if(t[k+1]==t[i])
k++;
nest[0][i]=k;
}
for(int i=1; i<=len; i++)
he[i]=he[nest[0][i]]+1;
}
int main() {
cin>>n;
while(n--) {
ans=1;
scanf("%s",t+1);
len=strlen(t+1);
m=ceil(log(len)/log(2));
q_nest();
for(int i=1; i<=m; i++)
for(int j=1; j<=len; j++)
nest[i][j]=nest[i-1][nest[i-1][j]];
for(int i=1; i<=len; i++) {
int k=i;
for(int j=m; j>=0; j--)
if(nest[j][k]*2>i)
k=nest[j][k];
ans=(1ll*ans*he[k])%1000000007;
}
printf("%d\n",ans);
}
return 0;
}
满分代码
博客
洛谷题解(包含各种满分代码)