首页 > 其他分享 >CF288E

CF288E

时间:2024-03-09 10:22:40浏览次数:22  
标签:pw CF288E int ret mod dp Mod

虚高 *2800,放模拟赛 T1 人均切了。

这是 zlt 说的,不是我说的,我还是觉得没那么虚高的。

首先显然是数位 dp。

一个关键点就是怎么计算 \(f_i\times f_{i+1}\)。会发现可以将为 \(4\) 的位置看作 \(0\),否则为 \(1\),则二进制下 \(f_{i+1}=f_i+1\)。此时问题就变成了进位所带来的贡献。

考虑一个数进位的条件及发生的变化。进位时,一个最大后缀 \(7\) 连续段会变成 \(4\),然后它前面接着的一个 \(4\) 会变成 \(7\),再前面的数全部不变。于是我们可以在数位 dp 的过程中找到那个 \(4\),然后后面的 \(7\) 都是确定的,直接预处理计数。

接下来,只用考虑在 \(f_i,f_{i+1}\) 前面同时加上一个数的转移了。设 \(f_i=a,f_{i+1}=b\),前面加上 \(x=4/7\times10^k\)。则原本 \(a\times b\) 的贡献会变成 \((x+a)\times(x+b)=x^2+x\times(a+b)+a\times b\)。所以可以在数位 dp 时记录选出 \(f_i,f_{i+1}\) 的方案数,所有 \(f_i,f_{i+1}\) 的方案的 \(f_i+f_{i+1}\) 的和,所有 \(f_i,f_{i+1}\) 的方案的 \(f_i\times f_{i+1}\) 的和,上述第三种情况可以根据上面列出的式子转移,其他两种情况也是好推的。

于是再套一些数位 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();
}

标签:pw,CF288E,int,ret,mod,dp,Mod
From: https://www.cnblogs.com/yinhee/p/18062323/CF288E

相关文章