CodeForces
来源:互联网 发布:php query 编辑:程序博客网 时间:2024/06/05 23:08
/* 求区间内有多少个数,能被它的每一位非0数字整除 非常有趣的数位dp,一个数能够被它每一位非0数字整除,意味着能整除这些数的lcm lcm可以在递归的时候直接求出来,问题在于怎么知道当前数是否被每一个非零位整除 因为1-9的最小公倍数为2520,例如一个数x,每一个非零位的lcm为y. 若x=z*y,因为2520=k*y,那么x%2520也一定是y的倍数。 另外如果直接开dp[20][2520][2520]会MLE,所以记录所有的最小公倍数离散化即可。 */#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>#include <cstdlib>#include <vector>using namespace std;#define LL long longconst int MOD = 2520;LL dp[20][50][2550];int dis[20];int Hash[2550];LL gcd(LL a, LL b){ return b?gcd(b,a%b):a;}LL dfs(int len, int num, int lcm, bool flag){ if(-1==len) return num%lcm == 0; if(!flag && ~dp[len][Hash[lcm]][num]) return dp[len][Hash[lcm]][num]; LL ans = 0; int end = flag?dis[len]:9; for(int i=0; i<=end; i++) ans += dfs(len-1, (num*10+i)%MOD, i?lcm*i/gcd(lcm,i):lcm, flag&&i==end); if(!flag) dp[len][Hash[lcm]][num] = ans; return ans;}LL solve(LL n){ int pos = 0; while(n){ dis[pos++] = n%10; n /= 10; } return dfs(pos-1, 0, 1, 1);}int main(){ int T; scanf("%d", &T); int cnt = 0; for(int i=1; i<=MOD; i++) if(MOD%i == 0) Hash[i] = cnt++; memset(dp, -1, sizeof(dp)); while(T--){ long long l, r; scanf("%lld%lld", &l, &r); printf("%lld\n", solve(r)-solve(l-1)); } return 0;}
阅读全文
0 0
- codeforces~~~
- Codeforces
- codeforces
- Codeforces
- codeforces
- codeforces
- Codeforces
- Codeforces
- CodeForces
- CodeForces
- CodeForces
- CodeForces
- CodeForces
- Codeforces
- Codeforces
- Codeforces
- Codeforces
- Codeforces
- C
- 将一个浮点数,转换为指定格式的字符串
- SDUT_CTF_WEB题目writeup
- Python复习-17.10.08
- jQuery插件的使用和写法
- CodeForces
- adb循环打印log
- Oracle数据库完整性约束
- SurfaceView原理简述
- 正则表达式总结
- QGIS中的python3和pyqt5问题解决
- Mongodb查询计划的生成
- 171006 逆向-EAT机制
- js判断日期