zoukankan      html  css  js  c++  java
  • 6831. 2020.10.24【NOIP提高A组】T1.lover

    表了一下,发现(dig)有值的数大概只有几万个,可以考虑做做。
    然后发现它要(gcd<=K),考虑分解质因数后(DP)。然后不会。

    考虑(DP),显然对答案有贡献的数位可以拆分成质因子。
    (f[x][0/1][a][b][c][d])表示当前到了第(x)位,是否有顶格,(gcd)(2^a*3^b*5^c*7^d)的方案数。
    显然可以用数位(DP)转移,转移不讲。

    (g[a][b][c][d])表示(f[0][a][b][c][d]+f[1][a][b][c][d])
    我们发现可以通过高维前缀和然后容斥来解决问题。
    (g)为后缀和后的(g),设(h)为两两间(gcd)(2^a*3^b*5^c*7^d)的方案数。
    (Solution 1)
    (h[a][b][c][d])显然可以用容斥来解决。
    (h[a][b][c][d]=g[a][b][c][d]^2-g[a+1][b][c][d]^2-g[a][b+1][c][d]^2-g[a][b][c+1][d]^2-g[a][b][c][d+1]^2+......)
    当然这种写法十分的麻烦(吧)

    (Solution 2)
    高维前缀和以后,设(p[a][b][c][d])表示(h)的后缀和
    那么可以惊奇地发现:(p)=(g*g)!!!
    是的,就是这么的神奇,求出(p)以后在逆推回去就得到(h)了。
    答案就是把所有(<=gcd)的方案数加起来。。。

    (Code(Solution 2))

    这数位(DP)和高维前缀和真是累死人不偿命。。。

    #include <cstdio>
    #include <cstring>
    #define mo 998244353
    #define db double
    #define ll long long
    #define mem(x, a) memset(x, a, sizeof x)
    #define mpy(x, y) memcpy(x, y, sizeof y)
    #define fo(x, a, b) for (int x = (a); x <= (b); x++)
    #define fd(x, a, b) for (int x = (a); x >= (b); x--)
    #define go(x) for (int p = tail[x], v; p; p = e[p].fr)
    #define plus(x, y) x = x + y >= mo ? x + y - mo : x + y
    #define nplus(x, y) x = x + mo - y >= mo ? x - y : x + mo - y
    using namespace std;
    const int fen[10][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}, 
    						{1, 0, 0, 0}, {0, 1, 0, 0},
    						{2, 0, 0, 0}, {0, 0, 1, 0},
    						{1, 1, 0, 0}, {0, 0, 0, 1},
    						{3, 0, 0, 0}, {0, 2, 0, 0}};
    int f[61][39][27][23], g[61][39][27][23], len, ans = 0;
    int las_[4];
    ll n, K, cf[19], cf0[4][60];
    bool nonono = 0;
    
    int get_len(ll x) {
    	int s = 0; while (x) s++, x /= 10;
    	cf[0] = 1; fo(i, 1, s) cf[i] = cf[i - 1] * 10;
    	return s;
    }
    
    
    int main()
    {
    	freopen("lover.in", "r", stdin);
    	freopen("lover.out", "w", stdout);
    	scanf("%lld%lld", &n, &K);
    	len = get_len(n);
    	
    	int fir_ = n / cf[len - 1] % 10;
    	fo(i, 1, fir_ - 1) f[fen[i][0]][fen[i][1]][fen[i][2]][fen[i][3]] = 1;
    	fo(i, 0, 3) las_[i] = fen[fir_][i];
    	
    	cf0[0][0] = cf0[1][0] = cf0[2][0] = cf0[3][0] = 1;
    	fo(i, 1, 59) cf0[0][i] = cf0[0][i - 1] << 1;
    	fo(i, 1, 37) cf0[1][i] = cf0[1][i - 1] * 3;
    	fo(i, 1, 25) cf0[2][i] = cf0[2][i - 1] * 5;
    	fo(i, 1, 21) cf0[3][i] = cf0[3][i - 1] * 7;
    	
    	fo(i, 2, len) {
    		int val = n / cf[len - i] % 10;
    		if (val == 0) nonono = 1;
    		mpy(g, f); mem(f, 0);
    		fo(j, 0, 59) {
    			if (cf0[0][j] > cf[i - 1]) break;
    			fo(k, 0, 37) {
    			if (cf0[0][j] * cf0[1][k] > cf[i - 1]) break;
    			fo(l, 0, 25) {
    			if (cf0[0][j] * cf0[1][k] * cf0[2][l] > cf[i - 1]) break;
    			fo(p, 0, 21) {
    			if (cf0[0][j] * cf0[1][k] * cf0[2][l] * cf0[3][p] > cf[i - 1]) break;
    			if (! g[j][k][l][p]) continue;
    			fo(q, 1, 9) {
    				if (j + fen[q][0] > 59 || k + fen[q][1] > 37 || l + fen[q][2] > 25 || p + fen[q][3] > 21) continue;
    				plus(f[j + fen[q][0]][k + fen[q][1]][l + fen[q][2]][p + fen[q][3]], g[j][k][l][p]);
    			}
    			}
    			}
    			}
    		}
    		
    		fo(q, 1, 9) plus(f[fen[q][0]][fen[q][1]][fen[q][2]][fen[q][3]], 1);
    		if (nonono == 0) {
    			fo(q, 1, val - 1)
    				plus(f[las_[0] + fen[q][0]][las_[1] + fen[q][1]][las_[2] + fen[q][2]][las_[3] + fen[q][3]], 1);
    		}
    		fo(j, 0, 3) las_[j] += fen[val][j];
    	}
    	if (nonono == 0) f[las_[0]][las_[1]][las_[2]][las_[3]]++;
    	/*
    	fo(j, 0, 59) fo(k, 0, 37) fo(l, 0, 25) fo(p, 0, 21) {
    		if (! f[j][k][l][p]) continue;
    		printf("%d %d %d %d, %lld
    ", j, k, l, p, cf0[0][j] * cf0[1][k] * cf0[2][l] * cf0[3][p]);
    		printf("%d
    ", f[j][k][l][p]);
    	}
    	return 0;
    	*/
    	fd(j, 59, 0) fd(k, 37, 0) fd(l, 25, 0) fd(p, 21, 0)
    		plus(f[j][k][l][p], f[j + 1][k][l][p]);
    	fd(j, 59, 0) fd(k, 37, 0) fd(l, 25, 0) fd(p, 21, 0)
    		plus(f[j][k][l][p], f[j][k + 1][l][p]);
    	fd(j, 59, 0) fd(k, 37, 0) fd(l, 25, 0) fd(p, 21, 0)
    		plus(f[j][k][l][p], f[j][k][l + 1][p]);
    	fd(j, 59, 0) fd(k, 37, 0) fd(l, 25, 0) fd(p, 21, 0)
    		plus(f[j][k][l][p], f[j][k][l][p + 1]);
    	fo(j, 0, 59) fo(k, 0, 37) fo(l, 0, 25) fo(p, 0, 21)
    		g[j][k][l][p] = (ll)f[j][k][l][p] * f[j][k][l][p] % mo;
    	fo(j, 0, 59) fo(k, 0, 37) fo(l, 0, 25) fo(p, 0, 21)
    		nplus(g[j][k][l][p], g[j + 1][k][l][p]);
    	fo(j, 0, 59) fo(k, 0, 37) fo(l, 0, 25) fo(p, 0, 21)
    		nplus(g[j][k][l][p], g[j][k + 1][l][p]);
    	fo(j, 0, 59) fo(k, 0, 37) fo(l, 0, 25) fo(p, 0, 21)
    		nplus(g[j][k][l][p], g[j][k][l + 1][p]);
    	fo(j, 0, 59) fo(k, 0, 37) fo(l, 0, 25) fo(p, 0, 21)
    		nplus(g[j][k][l][p], g[j][k][l][p + 1]);
    		
    	fo(j, 0, 59) {
    		if (cf0[0][j] > K) break;
    		fo(k, 0, 37) {
    		if (cf0[0][j] * cf0[1][k] > K) break;
    		fo(l, 0, 25) {
    		if (cf0[0][j] * cf0[1][k] * cf0[2][l] > K) break;
    		fo(p, 0, 21) {
    			if (cf0[0][j] * cf0[1][k] * cf0[2][l] * cf0[3][p] > K) break;
    			plus(ans, g[j][k][l][p]);
    		}
    	}
    	}
    	}
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    Mybatis Cause: java.lang.ClassNotFoundException: Cannot find class:
    java常见面试题及部分答案
    页面css样式找不到问题
    深入分析Java I/O的工作机制 (二)
    深入分析Java I/O的工作机制 (一)
    LifecycleProcessor not initialized
    几个java小例子
    idea 过段时间java程序包不存在问题 ?
    使用HttpClient发送Get/Post请求 你get了吗?
    Convert PIL Image to byte array?
  • 原文地址:https://www.cnblogs.com/jz929/p/13871004.html
Copyright © 2011-2022 走看看