CF288E
虚高 *2800,放模拟赛 T1 人均切了。
这是 zlt 说的,不是我说的,我还是觉得没那么虚高的。
首先显然是数位 dp。
一个关键点就是怎么计算
考虑一个数进位的条件及发生的变化。进位时,一个最大后缀
接下来,只用考虑在
于是再套一些数位 dp 基本操作即可。你不会数位 dp 我也讲不懂啊可能需要感性理解一下。
code:
点击查看代码
int n,m,b[13],c[13],f[N],g[N],pw[N],a[N],dp[N][3][2];
char s[N],t[N];bool pd[N];
il int Mod(int x,int y){return x+y>=mod?x+y-mod:x+y;}
int dfs(int u,int p,int lim){
if(u==n+1)return 0;
if(~dp[u][p][lim])return dp[u][p][lim];
int mx=lim?c[a[u]]:2,ret=0;
rep(i,1,mx){
int lm=lim&&i==mx;
if(i==1&&!lm){
if(p==0)ret=Mod(ret,1);
if(p==1)ret=Mod(ret,Mod(Mod(1ll*b[1]*pw[n-u]%mod,g[n-u]),Mod(1ll*b[2]*pw[n-u]%mod,f[n-u])));
if(p==2)ret=Mod(ret,(1ll*Mod(1ll*b[1]*pw[n-u]%mod,g[n-u])*Mod(1ll*b[2]*pw[n-u]%mod,f[n-u])%mod));
}
if(p==0)ret=Mod(ret,dfs(u+1,0,lm));
if(p==1)ret=Mod(ret,Mod(dfs(u+1,1,lm),2ll*b[i]*pw[n-u]%mod*dfs(u+1,0,lm)%mod));
if(p==2)ret=Mod(ret,Mod(dfs(u+1,2,lm),Mod(1ll*b[i]*pw[n-u]%mod*dfs(u+1,1,lm)%mod,1ll*b[i]*pw[n-u]%mod*b[i]%mod*pw[n-u]%mod*dfs(u+1,0,lm)%mod)));
}
return dp[u][p][lim]=ret;
}
int calc(char *s){
mems(dp,-1);
rep(i,1,n)a[i]=s[i]-'0';
pd[n+1]=1;
drep(i,n,1)pd[i]=pd[i+1]&(a[i]==b[2]);
return dfs(1,2,1);
}
void Yorushika(){
scanf("%s%s",s+1,t+1),n=strlen(s+1);
b[1]=4,b[2]=7;
f[0]=g[0]=0,pw[0]=1;
rep(i,1,n)f[i]=(10ll*f[i-1]+b[1])%mod,g[i]=(10ll*g[i-1]+b[2])%mod,pw[i]=10ll*pw[i-1]%mod;
c[b[1]]=1,c[b[2]]=2;
printf("%d\n",Mod(calc(t),mod-calc(s)));
}
signed main(){
int t=1;
// scanf("%d",&t);
while(t--)
Yorushika();
}