HDU 4321 Arcane Numbers 2
2016-03-19 18:27
330 查看
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4321
-------------------------------------------------------------------------------
虽然有更优美的做法 不过数据范围还是可以数位$DP$的
即把模型转化为 在区间内 $mod\ a = b\ mod\ a$ 的数所含$1$的个数之和
四维的数组分别记录 枚举到第$x$位 是否达到上限 $mod\ a$ 的余数 当前位是否为$1$ 这些状态
然后统计在这些状态下的数的个数$F$ 以及在这些状态下的数的总贡献 $G$
转移的话 $F$比较简单
$G$的话先把当前位之后的$G$全部转移上去 再把当前位根据$F$的大小算好贡献
之后就是一个记忆化搜索了
-------------------------------------------------------------------------------
虽然有更优美的做法 不过数据范围还是可以数位$DP$的
即把模型转化为 在区间内 $mod\ a = b\ mod\ a$ 的数所含$1$的个数之和
四维的数组分别记录 枚举到第$x$位 是否达到上限 $mod\ a$ 的余数 当前位是否为$1$ 这些状态
然后统计在这些状态下的数的个数$F$ 以及在这些状态下的数的总贡献 $G$
转移的话 $F$比较简单
$G$的话先把当前位之后的$G$全部转移上去 再把当前位根据$F$的大小算好贡献
之后就是一个记忆化搜索了
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; long long f[50][2][10010][2], g[50][2][10010][2], two[50]; int ti[50][2][10010][2]; bool num[50]; long long a, b, n, ans; int t, len, tt; void work(long long x) { memset(num, 0, sizeof num); len = 0; while(x) { num[++len] = x & 1; x >>= 1; } two[0] = 1 % a; for(int i = 1; i < len; ++i) two[i] = two[i - 1] * 2 % a; } long long dfs(int x, bool top, int r, bool one) { if(ti[x][top][r][one] == tt) return f[x][top][r][one]; ti[x][top][r][one] = tt; if(x == 0) { g[x][top][r][one] = (one && (r == b % a)); return f[x][top][r][one] = (r == b % a); } f[x][top][r][one] = g[x][top][r][one] = 0; if(top) { if(num[x]) { f[x][top][r][one] += dfs(x - 1, 1, (two[x - 1] + r) % a, 1); g[x][top][r][one] += g[x - 1][1][(two[x - 1] + r) % a][1]; f[x][top][r][one] += dfs(x - 1, 0, r, 0); g[x][top][r][one] += g[x - 1][0][r][0]; } else { f[x][top][r][one] += dfs(x - 1, 1, r, 0); g[x][top][r][one] += g[x - 1][1][r][0]; } } else { f[x][top][r][one] += dfs(x - 1, 0, (two[x - 1] + r) % a, 1); g[x][top][r][one] += g[x - 1][0][(two[x - 1] + r) % a][1]; f[x][top][r][one] += dfs(x - 1, 0, r, 0); g[x][top][r][one] += g[x - 1][0][r][0]; } g[x][top][r][one] += one * f[x][top][r][one]; return f[x][top][r][one]; } int main() { scanf("%d", &t); for(int ca = 1; ca <= t; ++ca) { scanf("%lld%lld%lld", &a, &b, &n); work(b); ++tt; dfs(len + 1, 1, 0, 0); ans = -g[len + 1][1][0][0]; work(b + n * a); ++tt; dfs(len + 1, 1, 0, 0); ans += g[len + 1][1][0][0]; printf("Case #%d: %lld\n", ca, ans); } return 0; }
相关文章推荐
- VS2008 断点不起作用
- 保存配置好的.config文件
- POJ 2226 Muddy Fields (最小点覆盖)
- ifndef系列
- 解决DWZ(JUI)的panel 点击关闭或者打开按钮 自己写的标签消失
- DNS主从自动同步
- 数据结构笔记-----查找
- Android 如何在Eclipse中查看Android API源码 及 support包源码
- linux内核设计与实现一书阅读整理 之第一二章整合
- 在windows环境下用python编写备份文件小程序
- Cadence Allegro 生成PDF,打印PCB
- Java遇见HTML——JSP篇之JSP指令与动作元素
- (2)ICE代理扮演的角色
- 第三周学习进度
- 构建之法阅读笔记03
- Java:List remove时候注意事项
- bzoj3157 3516 国王奇遇记
- 让html元素随浏览器的大小自适应垂直居中
- 第四周项目3-随机数函数应用与游戏(1)
- Android ListView 卡顿问题分析与解决方案