CF585F. Digits of Number Pi
题目大意
题解
裸题
建SAM,在SAM上面数位dp维护位置和当前长度即可
注意要先枚举新加的数,然后统一跳fail直到可以往下接,否则时间不能保证
时间复杂度O(10*nd^2)
code
#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define add(a,b) a=((a)+(b))%1000000007
#define mod 1000000007
#define ll long long
//#define file
using namespace std;
int a[51],b[2011],tr[2011][10],fa[2011],Len[2011],n,d,D,i,j,k,l,I,J,K,L,s,len,tot;
char S[1001],s1[51],s2[51];
ll ans,f[51][2011][26][2],F[2011][26][2];
namespace G{
int a[2011][2],ls[2011],len;
void New(int x,int y) {++len;a[len][0]=y;a[len][1]=ls[x];ls[x]=len;}
void dfs(int t)
{
int i;
b[++tot]=t;
for (i=ls[t]; i; i=a[i][1])
dfs(a[i][0]);
}
};
void copy(int t1,int t2) {memcpy(tr[t1],tr[t2],sizeof(tr[t2]));}
void New(int t,int x) {++len;if (tr[t][x]) copy(len,tr[t][x]);tr[t][x]=len;Len[len]=Len[t]+1;}
void build()
{
len=l=1;
fo(i,1,n)
{
New(l,S[i]-'0'),j=fa[l];
while (j && !tr[j][S[i]-'0']) tr[j][S[i]-'0']=len,j=fa[j];
if (!j) fa[len]=1;
else
if (Len[j]+1==Len[tr[j][S[i]-'0']]) fa[len]=tr[j][S[i]-'0'];
else
{
k=tr[j][S[i]-'0'],New(j,S[i]-'0');
fa[len]=fa[k],fa[len-1]=fa[k]=len;
j=fa[j];
while (tr[j][S[i]-'0']==k) tr[j][S[i]-'0']=len,j=fa[j];
}
l=tr[l][S[i]-'0'];
}
fo(i,2,len) G::New(fa[i],i);
G::dfs(1);
}
void dp(char st[51],int S)
{
fo(i,1,d) a[i]=st[i]-'0';
memset(f,0,sizeof(f));
fo(s,1,a[1])
if (tr[1][s])
++f[1][tr[1][s]][1][s<a[1]]; else ++f[1][1][0][s<a[1]];
fo(i,2,d)
{
fo(s,1,9)
if (tr[1][s])
++f[i][tr[1][s]][1][1]; else ++f[i][1][0][1];
}
fo(i,1,d-1)
{
I=i+1;
fo(s,0,9)
{
memcpy(F,f[i],sizeof(F));
fd(j,len,2)
{
fo(k,0,D)
{
fo(l,0,1)
if (!tr[b[j]][s])
{
if (k<D)
add(F[fa[b[j]]][Len[fa[b[j]]]][l],F[b[j]][k][l]);
else
add(F[fa[b[j]]][D][l],F[b[j]][k][l]);
F[b[j]][k][l]=0;
}
}
}
fo(j,1,len)
{
if (tr[j][s])
J=tr[j][s]; else J=j;
fo(k,0,D)
{
if (k<D)
K=k+(tr[j][s]>0);else K=D;
fo(l,0,1)
if (l || s<=a[i+1])
{
L=(s<a[i+1])?1:l;
add(f[I][J][K][L],F[j][k][l]);
}
}
}
}
}
fo(j,1,len)
{
if (S==-1)
add(ans,-f[d][j][D][1]);
else
add(ans,f[d][j][D][0]+f[d][j][D][1]);
}
}
int main()
{
#ifdef file
freopen("CF585F.in","r",stdin);
#endif
scanf("%s",S+1);n=strlen(S+1);
scanf("%s",s1+1);
scanf("%s",s2+1);
d=strlen(s1+1),D=d/2;
build();
dp(s1,-1),dp(s2,1);
printf("%lld\n",(ans+mod)%mod);
fclose(stdin);
fclose(stdout);
return 0;
}