D 简单的数论题

https://www.51nod.com/Contest/Problem.html#contestProblemId=4854

考虑 \(\varphi(x)=x*(1-\dfrac{1}{p_1})*(1-\dfrac{1}{p_2})*...*(1-\dfrac{1}{p_m})\)

又因为 \(f(x)=\prod a_i,a_i\in [0,9]\),也就是说,我们可以拆成若干个 \(2,3,5,7\) 的乘积,然后考虑 2 个相乘,注意下 \(\varphi(i*j)=\varphi(i)*\varphi(j),i\perp j\)\(\varphi(i*p_j)=\varphi(i)*p_j,p_j|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) {
//		cout<<pos<<" retg "<<lim<<" "<<zero<<" "<<a<<" "<<b<<" "<<c<<" "<<d<<'\n';
		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;
//	cout<<pos<<" retg "<<lim<<" "<<zero<<" "<<st<<" "<<mx<<" "<<a<<" "<<b<<" "<<c<<" "<<d<<'\n';
	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() {
//	int a=10000000; cout<<a*a%mod<<" "<<int*a*a%mod<<'\n';
	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;
	}
//	cout<<nn[1]<<" "<<nn[2]<<'\n';
	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++) {
//					if(!a&&!b&&!c&&!d) continue ;
					cnt[a][b][c][d]=dfs(tot,1,1,a,b,c,d);
//					cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<cnt[a][b][c][d]<<'\n';
//					int qwq=p2[a]*p3[b]%mod*p5[c]%mod*p7[d]%mod; 
//					mp[(a>0)][(b>0)][(c>0)][(d>0)]=(mp[(a>0)][(b>0)][(c>0)][(d>0)]+qwq*cnt[a][b][c][d]%mod)%mod;
					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(!a&&!b&&!c&&!d) continue ;
					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 ;
//									if(!i&&!j&&!k&&!z) continue ;
									int nw=mp[i][j][k][z];
//									cout<<a<<" "<<b<<" "<<c<<" "<<d<<" "<<i<<" "<<j<<" "<<k<<" "<<z<<" "<<nw<<' ';
									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;
//									cout<<nw<<'\n';
//									cout<<nw<<" "<<a<<" "<<b<<" "<<c<<" "<<d<<" "<<cnt[a][b][c][d]<<'\n'; 
//									if((ans+nw)>=mod) ans=ans+nw-mod; else ans=ans+nw;
									ans=(ans+nw)%mod;
								}
							}
						}
					}
				}
			}
		}
	}
	cout<<ans;
	return 0;
}

posted @ 2022-07-08 21:26  FxorG  阅读(39)  评论(0)    收藏  举报