2017年10月28日提高组 Num
来源:互联网 发布:sql insert 语法 编辑:程序博客网 时间:2024/06/07 19:35
Description
求区间 [ A , B ] 间的自然数中,0~9各出现了多少次。
Input
一行,两个数A,B
Output
一行10 个数,依次表示0 到9 的出现次数
[大致数据规模]
约50%的数据满足 B-A<=10^6;
约100%的数据满足1<=A<=B<=10^10。
Solution
据说很水的题目被我用复杂的方法a了。。
首先就想到数位dp,分成0~9分别做。用f[i][j][0/1]记录前i位二进制状态为j,是否贴着放的方案数。那么单独的答案就是二进制里面1的个数了
Code
#include <stdio.h>#include <string.h>#include <math.h>#include <iostream>#include <queue>#include <vector>#include <algorithm>#include <stack>#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)#define drp(i, st, ed) for (int i = st; i >= ed; i -= 1)#define erg(i, st) for (int i = ls[st]; i; i = e[i].next)#define fill(x, t) memset(x, t, sizeof(x))#define min(x, y) ((x)<(y)?(x):(y))#define max(x, y) ((x)>(y)?(x):(y))#define ld long double#define db double#define ll long long#define INF 0x3f3f3f3f#define N 1001#define E 1001#define L 1001ll f[21][4098][2], rec[4098];int digA[21], digB[21];inline int read() { int x = 0, v = 1; char ch = getchar(); for (; ch < '0' || ch > '9'; v *= (ch == '-')?(-1):(1), ch = getchar()); for (; ch <= '9' && ch >= '0'; (x *= 10) += ch - '0', ch = getchar()); return x * v;}inline void dfs(int dep, int stat, int fig, bool flag, int dig[]) { if (dep == dig[0] + 1) { f[dep][stat][flag] = rec[stat]; return ; } if (f[dep][stat][flag]) { return ; } int mx = 9; if (flag) { mx = dig[dep]; } rep(now, 0, mx) { dfs(dep + 1, (stat << 1) | (now == fig), fig, flag & (now == mx), dig); f[dep][stat][flag] += f[dep + 1][(stat << 1) | (now == fig)][flag & (now == mx)]; }}std:: stack<int> stack;inline void getDig(ll a, ll b) { while (!stack.empty()) { stack.pop(); } do { stack.push(a % 10); } while (a /= 10); digA[0] = 0; while (!stack.empty()) { digA[++ digA[0]] = stack.top(); stack.pop(); } while (!stack.empty()) { stack.pop(); } do { stack.push(b % 10); } while (b /= 10); digB[0] = 0; while (!stack.empty()) { digB[++ digB[0]] = stack.top(); stack.pop(); }}inline ll cal(int fig, int dig[]) { fill(f, 0); ll ret = 0; rep(i, 1, dig[1]) { dfs(2, (i == fig), fig, (i == dig[1]), dig); ret += f[2][(i == fig)][(i == dig[1])]; } rep(st, 2, dig[0]) { fill(f, 0); rep(i, 1, 9) { dfs(st + 1, (i == fig), fig, 0, dig); ret += f[st + 1][(i == fig)][0]; } } return ret;}int main(void) { // freopen("data.in","r",stdin); // freopen("myp.out","w",stdout); // std:: ios::sync_with_stdio(false); rep(i, 1, 4096) { rec[i] = rec[i >> 1] + (i & 1); } ll a, b; std:: cin >> a >> b; // scanf("%lld%lld",&) // ll a = read(); // ll b = read(); getDig(max(a - 1, 0), b); rep(i, 0, 9) { ll ans2 = cal(i, digB); ll ans1 = cal(i, digA); // printf("%d %d\n", ans1, ans2); if (a == 0 && i == 0) { ans2 += 1; } std:: cout << ans2 - ans1 << " "; // printf("%d ", ans2 - ans1); } return 0;}
阅读全文
0 0
- 2017年10月28日提高组 Num
- 2017年8月10日提高组T1 数学
- 2017年8月10日提高组T1 数学
- 2017年8月10日提高组T1 数学
- 2017年10月6日提高组T2 挖矿
- 2017年10月6日提高组T2 挖矿
- 2017年10月7日提高组T1 染色
- SSL2775 2017年10月19日提高组 新壳栈
- 2017年10月23日提高组T3 询问
- 2017年10月30日提高组T1 数论
- SSL2803 2017年10月28日提高组 sum(dp)
- 2017年8月7日提高组T1 呵呵
- 2017年8月7日提高组T1 呵呵
- 2017年8月7日提高组T1 呵呵
- 2017年8月7日提高组T1 根
- 2017年8月8日提高组T1 作业
- 2017年8月8日提高组T1 作业
- 2017年8月8日提高组T3 题目
- android.support.v4.app.FragmentActivity 获取不到问题;
- spring+springMVC+mybatis三大框架整合学习总结
- 静态和非静态的区别
- Fidder监控请求响应时间(毫秒)和请求IP
- CodeForces 844A Diversity (超级超级水唯一需要想得就是开个标记数组吧)
- 2017年10月28日提高组 Num
- 计算最大数
- java基础
- PAT乙级1015. 德才论(25)
- 状态模式
- 程序员面试的一些知识点(三)
- C# 用XiliumCefGlue做浏览器,JS和C#相互调用
- Error:java:JDK isn't specified for module
- wordpress主题无法正常使用