Gym - 101982D Count The Bits
# D. Count The Bits
数位DP
题意
给出 \(k\) 和 \(b\),计算 \([0, 2^b-1]\) 中所有 \(k\) 的倍数中有几个二进制 \(1\)。
题解
数位DP。
一个数加上 \(2^i-1\) 相当于在其二进制的第 \(i\) 位添上 \(1\)。
记录下\([0,2^i-1]\)(i = 1,2,3……,b-1,b)的数转换为二进制后1的个数。\(i\) 每增大 \(1\) 相当于 \([0,2^{i - 1}-1]\) 中的每个数加上 \(2^{i-1}\) 再加上原来的 \([0,2^{i - 1}-1]\) 。
因为加上 \(2^{i-1}\) 后余数会变。所以按照% k 所得的余数分类。
以k = 3 , b = 28 为例;
把\([0,2^{28}-1]\)数划分为
\([0,2^0-1]\) , \([0,2^1-1]\) , \([0,2^2-1]\) , \([0,2^3-1]\)……(\([0,2^i-1]\))
建立一个f[130][1010]的数组,横坐标表示 \(i\),纵坐标 \(j\) 表示 %\(k\) 的余数,里面存 \(x\) 的个数(\(x\epsilon [0,2^i-1]\),\(x\)%\(k\) == \(j\))。
当 \(i\) = 0 时,只存在一个数 \(0\),那么f[0][0] = 1;
当 \(i\) = 1 时候,\([1,1]\)可以用 \([0,0]\) + \(2^0\) 表示。那么原来的 0+1=1,% \(k\) 的余数就变成了1所以,f[1][1] = f[0][0] + f[0][1] = 1;
当 \(i\) = 2 时候,\([2,3]\)可以用 \([0,1]\) + \(2^1\) 表示。那么原来的 0+2=2,% \(k\) 的余数就变成了2所以,f[2][2] = f[1][2] + f[1][0] = 1 ;原来的1+2=3 , % \(k\) 的余数就变成了0,所以f[2][0] = f[1][1] + f[1][0] = 2; f[2][1] 还是原来的 f[1][1] = 1;
概括一下:f[i][j] = f[i - 1][j] + f[i-1][x] ( (x + \(2^{i-1}\)) % k == j )
建立一个g[130][1010]的数组,横坐标表示 \(i\),纵坐标 \(j\) 表示 %\(k\) 的余数,里面存 所有 \(x\) 转化为二进制后1的个数的总和 (\(x\epsilon [0,2^i-1]\),\(x\)%\(k\) == 纵坐标)。
g[i][j] = g[i-1][j] + g[i-1][x] + f[i-1][x] ( (x + \(2^{i-1}\)) % k == j )
g[i-1][j] 为原来就有的1数量。
纵坐标 为 \(x\) 的数 + \(2^{i-1}\) 后就变成了 %k == j 的数。
\(x\) 的数 + \(2^{i-1}\) 相当于在它们二进制的第 \(i\) 位 添一个1,在\([0,2^{i-1}-1]\)里有 f[i-1][j]个数,则在 \([0,2^i-1]\) 要多添加 f[i-1][j] 个1,然后再加上g[i-1][x]原来就有的1的数量。
所以g[i][j] = g[i-1][j] + g[i-1][x] + f[i-1][x] ( (x + \(2^{i-1}\)) % k == j )
上代码
代码
#include<iostream>
using namespace std;
long long f[130][1010] = {},g[130][1010] = {};
int main()
{
const long long mod = 1e9+9;
long long a = 1,k,b;
cin>>k>>b;
f[0][0] = 1;
for (int i = 1;i<=b;i++)
{
for (int j = 0;j<=k-1;j++)
{
f[i][j] += f[i-1][j];
f[i][(j+a)%k] += f[i-1][j];
g[i][j] += g[i-1][j];
g[i][(j+a)%k] += g[i-1][j] + f[i-1][j];
}
for (int j = 0; j < k; ++j) f[i][j] %= mod, g[i][j] %= mod;
a = (a * 2) % k;
}
cout<<g[b][0];
}
本文来自博客园,作者:Un-Defined,转载请保留本文署名Un-Defined,并在文章顶部注明原文链接:https://www.cnblogs.com/EIPsilly/p/15606190.html