• GMOJ 6831 lover


    GMOJ 6831 lover

    数位DP+高维前缀和

    我们设(h_{s, a, b, c, d})为乘积为(2^a imes3^b imes5^c imes7^d),其中(s)的第i位为0 / 1表示= / >这一维指定的指数。

    [ans=sum h_{S,a,b,c,d} cdot h_{T,a,b,c,d} quad (Tsubseteq complement_US) ]

    就是说当你(S_i)为1时,(T_i)一定为0,当(S_i)为0时,(T_i)可以为0/1。

    #include <cstdio>
    
    #define inc(x, y) (x=(x+(y))%mods)
    #define sqr(x) ((x)*(x)%mods)
    #define min(x, y) ((x)<(y) ? (x) : (y))
    
    using namespace std;
    
    typedef long long ll;
    const int maxl=18, mods=998244353, prim[4]={2, 3, 5, 7};
    
    void toArray(ll x, int a[]) {
    	a[0] = 0;
    	for (; x>0; x/=10) a[++a[0]] = x%10;
    }
    
    void initPri(int n, int a[]) {
    	for (int i=0; i<4; i++) {
    		a[i] = 0;
    		for (int t=prim[i]; n%t==0; a[i]++, t*=prim[i]);
    	}
    }
    
    int main() {
    	freopen("lover.in", "r", stdin);
    	freopen("lover.out", "w", stdout);
    
    	static ll f[maxl+1][3*maxl+1][2*maxl+1][maxl+1][maxl+1][2], h[16][3*maxl+2][2*maxl+2][maxl+2][maxl+2];
    	static int t[maxl+1], pi[10][4];
    	ll n, k;
    	scanf("%lld %lld", &n, &k);
    	toArray(n, t);
    	for (int i=1; i<10; i++) initPri(i, pi[i]);
    
    	f[0][0][0][0][0][0] = f[0][0][0][0][0][1] = 1;
    	for (int i=1; i<=t[0]; i++) {
    		for (int j=1; j<10; j++) {
    			for (int a=pi[j][0]; a<=3*i; a++) {
    				for (int b=pi[j][1]; b<=2*i; b++) {
    					for (int c=pi[j][2]; c<=i; c++) {
    						for (int d=pi[j][3]; d<=i; d++) {
    							int o=a-pi[j][0], 
    								p=b-pi[j][1], 
    								q=c-pi[j][2], 
    								r=d-pi[j][3];
    							inc(f[i][a][b][c][d][0],
    									f[i-1][o][p][q][r][0]);
    							if (j<t[i]) {
    								inc(f[i][a][b][c][d][1],
    										f[i-1][o][p][q][r][0]);
    							} else if (j==t[i]) {
    								inc(f[i][a][b][c][d][1],
    										f[i-1][o][p][q][r][1]);
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    
    	for (int i=1; i<=t[0]; i++) {
    		for (int a=0; a<=3*i; a++) {
    			for (int b=0; b<=2*i; b++) {
    				for (int c=0; c<=i; c++) {
    					for (int d=0; d<=i; d++) {
    						inc(h[0][a][b][c][d], f[i][a][b][c][d][i==t[0]]);
    					}
    				}
    			}
    		}
    	}
    
    	for (int i=1; i<16; i++) {
    		int j[4], pos, nj[4], ni;
    		for (pos=0; ((i>>pos)&1)==0; pos++);
    		ni = i^(1<<pos);
    		for (j[0]=3*t[0]; j[0]>=0; j[0]--) {
    			for (j[1]=2*t[0]; j[1]>=0; j[1]--) {
    				for (j[2]=t[0]; j[2]>=0; j[2]--) {
    					for (j[3]=t[0]; j[3]>=0; j[3]--) {
    						for (int k=0; k<4; k++) nj[k]=j[k];
    						nj[pos]++;
    						h[i][j[0]][j[1]][j[2]][j[3]] =
    							(h[i][nj[0]][nj[1]][nj[2]][nj[3]] +
    							 h[ni][nj[0]][nj[1]][nj[2]][nj[3]])%mods;
    					}
    				}
    			}
    		}
    	}
    
    	int a, b, c, d;
    	ll o, p, q, r, ans=0;
    	for (a=0, o=1; a<=3*t[0] && o<=k; a++, o*=2) {
    		for (b=0, p=1; b<=2*t[0] && o*p<=k; b++, p*=3) {
    			for (c=0, q=1; c<=t[0] && o*p*q<=k; c++, q*=5) {
    				for (d=0, r=1; d<=t[0] && o*p*q*r<=k; d++, r*=7) {
    					for (int i=0; i<16; i++) {
    						int t=15^i;
    						inc(ans, h[i][a][b][c][d]*h[t][a][b][c][d]%mods);
    						for (int j=(t-1)&t; j!=t; j=(j-1)&t) {
    							inc(ans, h[i][a][b][c][d]*h[j][a][b][c][d]%mods);
    						}
    					}
    				}
    			}
    		}
    	}
    
    	printf("%lld", ans);
    
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
    
  • 相关阅读:
    采集智能电表
    未能写入输出文件“c:\WINDOWS\Microsoft.NET\Framework\.....dll”“拒绝访问。
    随笔写写jquery
    随便写写,,
    写写Ajaxpro
    C# 给程序加日志功能。
    Oracle_Database_11g_标准版_企业版__下载地址_详细列表
    通过C#发送自定义的html格式邮件
    C# 加密解密链接字符串
    获取本地 有线 正在使用的网卡信息
  • 原文地址:https://www.cnblogs.com/BunnyLutts/p/13871252.html
Copyright © 2020-2023  润新知