zoukankan      html  css  js  c++  java
  • CodeForces 55D Beautiful numbers 数位DP+数学

    题意大概是,判断一个正整数区间内有多少个整数能被它自身的每一个非零的数字整除。

    因为每一个位置上的整数集s = {0,1,2,3,4,5,6,7,8,9} lcm(s) = 2520

    现在有一个整数t是由s中一个或者多个数字构成的,记为abcde,显然t = a*10^4+b*10^3+c*10^2+d*10^1+e

    要使得t能被a,b,c,d,e整除,必然有t % lcm(a,b,c,d,e) = 0 因为a,b,c,d,e去重之后一定是s的一个子集,所以lcm(s)一定是lcm(a,b,c,d,e)的倍数,所以只要

    t % lcm(s) % lcm(a,b,c,d,e) = 0 满足答案。

    一开始不知道这道题应该怎么存储状态,因为随着数字的变化,这个lcm(a,b,c,d,e)是会改变的,没法直接存储对lcm(a,b,c,d,e)的余数,但是lcm(s)是不变的,所以我们只要存储lcm(s)的余数和lcm(a,b,c,d,e)就好了,因为一共就九个数字,lcm一共只有48个,所以复杂度为lcm(s)*48*maxlen

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <string>
    #include <iostream>
    #include <map>
    #include <cstdlib>
    #include <list>
    #include <set>
    #include <queue>
    #include <stack>
    
    using namespace std;
    
    typedef long long LL;
    const int maxn = 20;
    const int mod = 2520;
    int lim[maxn],len;
    LL f[maxn][50][mod];
    map<int,int> st;
    int ccon[(1 << 10)],clcm[50];
    
    void getlim(LL num) {
        len = 0;
        memset(lim,0,sizeof(lim));
        while(num) {
            lim[len++] = num % 10;
            num /= 10;
        }
    }
    
    LL gcd(LL a,LL b) {
        return b == 0 ? a : gcd(b,a % b);
    }
    
    LL lcm(LL a,LL b) {
        return a / gcd(a,b) * b;
    }
    
    void init() {
        int cnt = 0;
        for(int i = 1;i < (1 << 10);i++) {
            int nlcm = 1;
            for(int j = 1;j <= 9;j++) if(i & (1 << j)) {
                nlcm = lcm(nlcm,j);
            }
            if(!st.count(nlcm)) {
                st[nlcm] = cnt;
                clcm[cnt++] = nlcm;
            }
            ccon[i] = st[nlcm];
        }
        ccon[0] = -1;
    }
    
    LL dfs(int now,int mask,int rest,int bound) {
        if(now == 0) {
            if(mask <= 1) return 0;
            return rest % clcm[ccon[mask]] == 0;
        }
        LL &note = f[now][ccon[mask]][rest];
        if(!bound && note != -1 && mask > 1) return note;
        int m = bound ? lim[now - 1] : 9;
        LL ret = 0;
        for(int i = 0;i <= m;i++) {
            ret += dfs(now - 1,mask | (1 << i),(rest * 10 + i) % mod,i == m && bound);
        }
        if(!bound && mask > 1) note = ret;
        return ret;
    }
    
    LL solve(LL num) {
        getlim(num);
        return dfs(len,0,0,1);
    }
    
    int main() {
        memset(f,-1,sizeof(f));
        init();
        int T; cin >> T;
        while(T--) {
            LL a,b; cin >> a >> b;
            cout << solve(b) - solve(a - 1) << endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    LR和SVM的相同和不同
    Logistic Regression理论总结
    LibSVM源码剖析(java版)
    CTR预估中的贝叶斯平滑方法(二)参数估计和代码实现
    支持向量机(SVM)中的 SMO算法
    《这就是搜索引擎》框架图
    Leetcode 初刷(1)
    tf中softmax_cross_entropy_with_logits与sparse_softmax_cross_entropy_with_logits
    python 判断是否为中文
    sklearn使用小记GridSearchCV
  • 原文地址:https://www.cnblogs.com/rolight/p/3891715.html
Copyright © 2011-2022 走看看