HDU 4321 Arcane Numbers 2

题目链接: 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$的大小算好贡献

之后就是一个记忆化搜索了

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <algorithm>
 5 using namespace std;
 6 long long f[50][2][10010][2], g[50][2][10010][2], two[50];
 7 int ti[50][2][10010][2];
 8 bool num[50];
 9 long long a, b, n, ans;
10 int t, len, tt;
11 void work(long long x)
12 {
13     memset(num, 0, sizeof num);
14     len = 0;
15     while(x)
16     {
17         num[++len] = x & 1;
18         x >>= 1;
19     }
20     two[0] = 1 % a;
21     for(int i = 1; i < len; ++i)
22         two[i] = two[i - 1] * 2 % a;
23 }
24 long long dfs(int x, bool top, int r, bool one)
25 {
26     if(ti[x][top][r][one] == tt)
27         return f[x][top][r][one];
28     ti[x][top][r][one] = tt;
29     if(x == 0)
30     {
31         g[x][top][r][one] = (one && (r == b % a));
32         return f[x][top][r][one] = (r == b % a);
33     }
34     f[x][top][r][one] = g[x][top][r][one] = 0;
35     if(top)
36     {
37         if(num[x])
38         {
39             f[x][top][r][one] += dfs(x - 1, 1, (two[x - 1] + r) % a, 1);
40             g[x][top][r][one] += g[x - 1][1][(two[x - 1] + r) % a][1];
41             f[x][top][r][one] += dfs(x - 1, 0, r, 0);
42             g[x][top][r][one] += g[x - 1][0][r][0];
43         }
44         else
45         {
46             f[x][top][r][one] += dfs(x - 1, 1, r, 0);
47             g[x][top][r][one] += g[x - 1][1][r][0];
48         }
49     }
50     else
51     {
52         f[x][top][r][one] += dfs(x - 1, 0, (two[x - 1] + r) % a, 1);
53         g[x][top][r][one] += g[x - 1][0][(two[x - 1] + r) % a][1];
54         f[x][top][r][one] += dfs(x - 1, 0, r, 0);
55         g[x][top][r][one] += g[x - 1][0][r][0];
56     }
57     g[x][top][r][one] += one * f[x][top][r][one];
58     return f[x][top][r][one];
59 }
60 int main()
61 {
62     scanf("%d", &t);
63     for(int ca = 1; ca <= t; ++ca)
64     {
65         scanf("%lld%lld%lld", &a, &b, &n);
66         work(b);
67         ++tt;
68         dfs(len + 1, 1, 0, 0);
69         ans = -g[len + 1][1][0][0];
70         work(b + n * a);
71         ++tt;
72         dfs(len + 1, 1, 0, 0);
73         ans += g[len + 1][1][0][0];
74         printf("Case #%d: %lld
", ca, ans);
75     }
76     return 0;
77 }
原文地址:https://www.cnblogs.com/sagitta/p/5295912.html