[codeforces 55]D. Beautiful numbers

试题描述

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.

输入

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 should contain t numbers — answers to the queries, one number per line — quantities of beautiful numbers in given intervals (from li to ri, inclusively).

输入示例


输出示例


数据规模及约定

见“输入

题解

“能同时被所有数位上的数字整除”等价于“能被所有数位上数字的最大公约数整除”。于是设 f[i][k][m] 表示一个 i 位的数,所有数字的最小公倍数等于 k,且这个数为 m。等等,状态 m 都知道这个数了,那 dp 个啥?别着急,我们一步步优化。

我们知道 lcm(1, 2, 3, 4, 5, 6, 7, 8, 9) = 2520(就是1~9的最小公倍数),那么对于刚才 m 的那一维状态是没有必要太大的,将这维状态对 2520 取个模就好了,即 m 表示这个数对 mod 2520 的值。

还有,1~9 这些数中,所有可能出现的最小公倍数只有 48 个(这个不妨读者自己写程序统计一下),所以离散一波 k 就变成最大只有 48 的数了。

最后状态数大概是:19 * 48 * 2520 = 2298240。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
#define LL long long LL read() {
LL x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 21
#define maxm 2521
#define maxc 49
int Lcm[maxc], cl, id[maxm], Gcd[maxm][maxm];
bool tmp[maxm];
LL f[maxn][maxc][maxm], ten[maxn]; int gcd(int x, int y){ return !y ? x : gcd(y, x % y); } int get(int l, int x) {
int nl;
if(!x && !l) nl = 0;
if(x && l) nl = l * x / Gcd[l][x];
if(!x && l) nl = l;
if(x && !l) nl = x;
return nl;
} int num[maxn];
LL sum(LL x) {
int cnt = 0; LL tx = x;
while(x) num[++cnt] = x % 10, x /= 10;
LL ans = 0; int l = 1;
for(int i = cnt; i; i--) {
for(int j = 0; j < num[i]; j++) {
int nl = get(l, j);
for(int k = 0; k <= cl; k++) {
int nnl = get(nl, Lcm[k]);
LL t;
if(i < cnt) t = (tx / ten[i] * ten[i] + ten[i-1] * j) % 2520;
else t = ten[i-1] * j % 2520;
for(int m = 0; m < maxm - 1; m += nnl) {
int M = (m - t + 2520) % 2520; if(M < 0) continue;
if(f[i-1][k][M]) ans += f[i-1][k][M];
}
}
}
l = get(l, num[i]);
}
if(tx % l == 0) ans++;
return ans;
} int main() {
for(int i = 1; i < maxm; i++)
for(int j = 1; j < maxm; j++) Gcd[i][j] = gcd(i, j); tmp[1] = 1;
for(int j = 2; j <= 9; j++)
for(int x = maxm - 1; x; x--)
if(tmp[x]) tmp[x*j/Gcd[x][j]] = 1;
for(int i = 1; i < maxm; i++)
if(tmp[i]) Lcm[++cl] = i, id[i] = cl; ten[0] = 1;
for(int i = 1; i < maxn; i++) ten[i] = ten[i-1] * 10; f[0][0][0] = 1;
for(int j = 0; j <= 9; j++) f[1][id[j]][j] = 1;
for(int i = 1; i < maxn - 1; i++)
for(int k = 0; k <= cl; k++)
for(int m = 0; m < maxm; m++) if(f[i][k][m]) {
int l = Lcm[k];
for(int x = 0; x <= 9; x++) {
int nl = get(l, x);
f[i+1][id[nl]][(ten[i]*x+m)%2520] += f[i][k][m];
}
}
int T = read();
while(T--) {
LL l = read(), r = read();
printf("%I64d\n", sum(r) - sum(l - 1));
} return 0;
}

[codeforces 55]D. Beautiful numbers的更多相关文章

  1. CF 55 D. Beautiful numbers

    D. Beautiful numbers 链接 题意: 求[L,R]中多少个数字可以整除它们的每一位上的数字. 分析: 要求模一些数字等于0等价于模它们的lcm等于0,所以可以记录当前出现的数字的lc ...

  2. 【Codeforces 300C】Beautiful Numbers

    [链接] 我是链接,点我呀:) [题意] 让你找到长度为n的数字 这个数字只由a或者b组成 且这n个数码的和也是由a或者b组成的 求出满足这样要求的数字的个数 [题解] 枚举答案数字中b的个数为y,那 ...

  3. CF D. Beautiful numbers (数位dp)

    http://codeforces.com/problemset/problem/55/D Beautiful Numbers : 这个数能整除它的全部位上非零整数.问[l,r]之间的Beautifu ...

  4. codeforces 55D - Beautiful numbers(数位DP+离散化)

    D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

  5. Codeforces Beta Round #51 D. Beautiful numbers 数位dp

    D. Beautiful numbers Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/55/p ...

  6. codeforces Beautiful Numbers

    来源:http://codeforces.com/problemset/problem/1265/B   B. Beautiful Numbers   You are given a permutat ...

  7. Codeforces Round #181 (Div. 2) C. Beautiful Numbers 排列组合 暴力

    C. Beautiful Numbers 题目连接: http://www.codeforces.com/contest/300/problem/C Description Vitaly is a v ...

  8. Codeforces Beta Round #51 D. Beautiful numbers

    D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

  9. CodeForces 55D "Beautiful numbers"(数位DP+离散化处理)

    传送门 参考资料: [1]:CodeForces 55D Beautiful numbers(数位dp&&离散化) 我的理解: 起初,我先定义一个三维数组 dp[ i ][ j ][ ...

随机推荐

  1. PHP 数据库抽象层pdo

    PDO是PHP数据对象(PHP Data Object)的缩写. pdo就是一个"数据库访问抽象层",作用是统一各种数据库的访问接口,能够轻松地在不同数据库之间进行切换,使得数据库 ...

  2. javascript之查找数组中最小/最大的数

    实现原理:和数组的顺序查找很类似,都是逐个数据的比对. 废话不多说~ 代码如下: /* * 参数说明: * array:传入数组 ,例如:var arr = [5,7,66,78,99,103,126 ...

  3. ASP------如何读取文件内容

    <body> @{ var dataFile = Server.MapPath("~/App_Data/Persons.txt"); Array list = File ...

  4. select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET

    http://hi.baidu.com/%B1%D5%C4%BF%B3%C9%B7%F0/blog/item/e7284ef16bcec3c70a46e05e.html select函数用于在非阻塞中 ...

  5. 20145212 《Java程序设计》第10周学习总结

    20145212 <Java程序设计>第10周学习总结 学习内容总结 一.Java的网络编程 网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. java.net ...

  6. Java数据结构的特点

  7. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【七】——实现资源的分页

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 这篇文章我们将使用不同的方式实现手动分页(关于高端大气上档次的OData本文暂不涉及,但有可 ...

  8. 第1章 JavaScript简介

    概述:Javascript是一种依赖于网页浏览器的脚本语言.是一种脚本语言.由Netscape和Sun共同开发.与Java没有什么关系.作为一种语言标准,而被称为ECMACcript.一个JS的实现包 ...

  9. Shared Library Search Paths

    在使用CodeLite编译动态库的时候,可以通过在Linker > Linker Options中添加: -install_name @executable_path/libXXX.so 的方式 ...

  10. C#和SQL实现的字符串相似度计算代码分享

    http://www.jb51.net/article/55941.htm C#实现: 复制代码 代码如下: #region 计算字符串相似度        /// <summary>   ...