CF585F. Digits of Number Pi
阿新 • • 發佈:2020-09-12
題目大意
題解
裸題
建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; }