zoukankan      html  css  js  c++  java
  • [CF55D]Beautiful numbers

    题目大意:多次询问,询问区间$[l,r]$中,能被它自己的每一位数上的数整除的数的个数

    题解:数位$DP$,$dp_{i,j}$表示到了第$i$位,前几位表示的数模$2520(LCM(1,2,dots,9))$的值为$j$的方案数

    卡点:数组开小,溢出(话说快$ ext{NOIP}$了,我还经常这样,是不是要挂)

    C++ Code:

    #include <cstdio>
    #define maxn 2530
    const int mod = 2520;
    
    int Tim;
    int ret[maxn], mp[maxn];
    long long f[20][maxn][50];
    int num[20];
    int gcd(int a, int b) {
    	if (!b) return a;
    	else return gcd(b, a % b);
    }
    int __lcm(int a, int b) {
    	if (!a || !b) return a | b;
    	return a * b / gcd(a, b);
    }
    long long calc(int x, int sum, int lcm, bool lim) {
    	if (!x) return (sum % ret[lcm] == 0);
    	long long F = f[x][sum][lcm];
    	if (!lim && ~F) return F;
    	F = 0;
    	for (int i = lim ? num[x] : 9, op = 1; ~i; i--, op = 0) {
    		F += calc(x - 1, (sum * 10 + i) % mod, mp[__lcm(ret[lcm], i)], lim && op);
    	}
    	if (!lim) f[x][sum][lcm] = F;
    	return F;
    }
    long long solve(long long x) {
    	int tot = 0;
    	while (x) {
    		num[++tot] = x % 10;
    		x /= 10;
    	}
    	return calc(tot, 0, 0, true);
    }
    int tot;
    int main() {
    	scanf("%d", &Tim);
    	for (int i = 1; i <= 2520; i++) if (mod % i == 0) mp[i] = tot, ret[tot++] = i;
    	__builtin_memset(f, -1, sizeof f);
    	while (Tim --> 0) {
    		long long l, r;
    		scanf("%lld%lld", &l, &r);
    		printf("%lld
    ", solve(r) - solve(l - 1));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    PDIUSBD12指令
    (转)USB的VID和PID,以及分类(Class,SubClass,Protocol)
    静态测试
    一种循环buffer结构
    RL78 芯片复位指令
    XModem协议
    位反转的最佳算法
    CCP 协议
    AUTOSAR 架构
    HEX 文件格式
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9780187.html
Copyright © 2011-2022 走看看