Codeforces Beta Round #51---D. Beautiful numbers(數位dp, 巧妙),

來源:互聯網
上載者:User

Codeforces Beta Round #51---D. Beautiful numbers(數位dp, 巧妙),

Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits. We will not argue with this and just count the quantity of beautiful numbers in given ranges.
Input

The first line of the input contains the number of cases t (1 ≤ t ≤ 10). Each of the next t lines contains two natural numbers li and ri (1 ≤ li ≤ ri ≤ 9 ·1018).

Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preffered to use cin (also you may use %I64d).
Output

Output should contain t numbers — answers to the queries, one number per line — quantities of beautiful numbers in given intervals (from li to ri, inclusively).
Sample test(s)
Input

1
1 9

Output

9

Input

1
12 15

Output

2

這題做法真的很精妙
如果一個數可以被它每一位上的數整除,那一定可以被那些數的LCM整除,最大的LCM是2520,因此那些數一定能被2520的因子某個整除
設dp[cur][rest][lcm]表示到第cur位,前面的數組成的數對2520模數為rest,之前的數的lcm為lcm的數的個數,直接這樣會超記憶體,所以第三維離散化一下

前面的數組成的數對2520模數後為什麼對答案沒有影響呢?
設這個數為2520 * k + b,對lcm模數,lcm是2520的一個因子,因此:
(2520 * k + b) % lcm = b % lcm
所以不影響

然後就是數位dp的事情了
顯然要用64位整數

/*************************************************************************    > File Name: cf55d.cpp    > Author: ALex    > Mail: zchao1995@gmail.com     > Created Time: 2015年02月23日 星期一 22時25分40秒 ************************************************************************/#include <map>#include <set>#include <queue>#include <stack>#include <vector>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const double pi = acos(-1);const int inf = 0x3f3f3f3f;const double eps = 1e-15;typedef long long LL;typedef pair <int, int> PLL;LL dp[33][2600][60];int LCM_ARR[60];int HASH[3000];int cnt;int bit[30];LL gcd (LL a, LL b){    return b ? gcd (b, a % b) : a;}LL LCM (LL a, LL b){    return a / gcd (a, b) * b;}LL dfs (int cur, int rest, int ind, bool flag, bool zero){    if (cur == -1)    {        if (zero)        {            return 0;        }        return (rest % LCM_ARR[ind] == 0);    }    if (!flag && ~dp[cur][rest][ind])    {        return dp[cur][rest][ind];    }    LL ans = 0;    int end = flag ? bit[cur] : 9;    for (int i = 0; i <= end; ++i)    {        if (zero && !i)        {            ans += dfs (cur - 1, 0, 0, flag && (i == end), 1);        }        else if (zero && i)        {            ans += dfs (cur - 1, i, HASH[i], flag && (i == end), 0);        }        else        {            if (i == 0)            {                ans += dfs (cur - 1, rest * 10 % 2520, ind, flag && (i == end), zero && (i == 0));                continue;            }            int lcm = LCM (LCM_ARR[ind], i);            ans += dfs (cur - 1, (rest * 10 + i) % 2520, HASH[lcm], flag && (i == end), zero && (i == 0));        }    }    if (!flag)    {        dp[cur][rest][ind] = ans;    }    return ans;}LL calc (LL n){    int ret = 0;    while (n)    {        bit[ret++] = n % 10;        n /= 10;    }    return dfs (ret - 1, 0, 1, 1, 1);}int main (){    cnt = 0;    memset (dp, -1, sizeof(dp));    for (int i = 1; i <= 2520; ++i)    {        if (2520 % i == 0)        {            LCM_ARR[++cnt] = i;            HASH[i] = cnt;        }    }    LL l, r;    int t;    scanf("%d", &t);    while (t--)    {        cin >> l >> r;        cout << calc (r) - calc (l - 1) << endl;    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.