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];
}
posted @ 2021-11-26 09:38  Un-Defined  阅读(37)  评论(0编辑  收藏  举报