https://www.51nod.com/Contest/Problem.html#contestProblemId=4854
考虑 φ(x)=x∗(1−1p1)∗(1−1p2)∗...∗(1−1pm)
又因为 f(x)=∏ai,ai∈[0,9],也就是说,我们可以拆成若干个 2,3,5,7 的乘积,然后考虑 2 个相乘,注意下 φ(i∗j)=φ(i)∗φ(j),i⊥j,φ(i∗pj)=φ(i)∗pj,pj|i。
#include <bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
const int mod=998244353;
int fpow(int x,int y) {
int res=1; x%=mod;
while(y) {
if(y&1) res=1ll*res*x%mod;
y>>=1; x=1ll*x*x%mod;
} return res;
}
const int INV2=fpow(2,mod-2),INV3=2*fpow(3,mod-2)%mod,INV5=4*fpow(5,mod-2)%mod,INV7=6*fpow(7,mod-2)%mod;
int f[20][60][40][20][20];
int mp[2][2][2][2];
int cnt[60][40][20][20];
int nn[20],n,tot;
int dfs(int pos,int lim,int zero,int a,int b,int c,int d) {
if(a<0||b<0||c<0||d<0) return 0;
if(!pos) {
if(zero) return 0;
if(a==0&&b==0&&c==0&&d==0) return 1;
return 0;
}
if(!lim&&!zero&&~f[pos][a][b][c][d]) return f[pos][a][b][c][d];
int mx=lim?nn[pos]:9,st=(!zero)?1:0;
int qwq=0;
for(int i=st;i<=mx;i++) {
int na=a,nb=b,nc=c,nd=d;
if(i==2) --na;
if(i==3) --nb;
if(i==4) na-=2;
if(i==5) --nc;
if(i==6) --na,--nb;
if(i==7) --nd;
if(i==8) na-=3;
if(i==9) nb-=2;
qwq=(qwq+dfs(pos-1,lim&(i==mx),zero&(i==0),na,nb,nc,nd))%mod;
}
if(!lim&&!zero) f[pos][a][b][c][d]=qwq;
return qwq;
}
int p2[62],p3[62],p5[62],p7[62];
signed main() {
cin.tie(0); ios::sync_with_stdio(false);
memset(f,-1,sizeof(f));
p2[0]=p3[0]=p5[0]=p7[0]=1;
for(int i=1;i<=60;i++) {
p2[i]=p2[i-1]*2%mod;
p3[i]=p3[i-1]*3%mod;
p5[i]=p5[i-1]*5%mod;
p7[i]=p7[i-1]*7%mod;
}
cin>>n;
while(n) {
nn[++tot]=n%10; n/=10;
}
for(int a=0;a<=tot*3;a++) {
for(int b=0;b<=min(2*(tot-a/3),tot*3-a);b++) {
for(int c=0;c<=min(tot-a/3-b/2,tot*3-a-b);c++) {
for(int d=0;d<=min(tot-a/3-b/2-c,tot*3-a-b-c);d++) {
cnt[a][b][c][d]=dfs(tot,1,1,a,b,c,d);
int qwq=p2[a]*p3[b]%mod*p5[c]%mod*p7[d]%mod;
bool aa=(a>0),bb=(b>0),cc=(c>0),dd=(d>0);
mp[aa][bb][cc][dd]=(mp[aa][bb][cc][dd]+qwq*cnt[a][b][c][d]%mod)%mod;
}
}
}
}
int ans=0;
for(int a=0;a<=1;a++) {
for(int b=0;b<=1;b++) {
for(int c=0;c<=1;c++) {
for(int d=0;d<=1;d++) {
if(!mp[a][b][c][d]) break ;
for(int i=0;i<=1;i++) {
for(int j=0;j<=1;j++) {
for(int k=0;k<=1;k++) {
for(int z=0;z<=1;z++) {
if(!mp[i][j][k][z]) break ;
int nw=mp[i][j][k][z];
if(a||i) nw=nw*INV2%mod;
if(b||j) nw=nw*INV3%mod;
if(c||k) nw=nw*INV5%mod;
if(d||z) nw=nw*INV7%mod;
nw=nw*mp[a][b][c][d]%mod;
ans=(ans+nw)%mod;
}
}
}
}
}
}
}
}
cout<<ans;
return 0;
}
__EOF__
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!