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;
}
posted @ 2020-09-12 21:42  gmh77  阅读(197)  评论(0编辑  收藏  举报