[UVALive4864] Bit Counting && 数位DP

本文介绍了一种解决特定二进制位计数问题的方法,通过使用C++编程实现,该算法能高效地统计给定范围内整数的二进制表示中1的个数,并针对不同数量的1进行计数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

可以很容易的发现从N1开始的所有值都小于64 那么其实就是统计二进制中1的个数为1 ~ 63的数字各有多少

#include<cstdio>    
#include<algorithm>    
#include<cstring>    
#include<vector>    
#include<queue>  
#include<deque>  
#include<iostream>
#define SF scanf    
#define PF printf    
using namespace std;
typedef long long LL;
const int MAXN = 64;
int bit[MAXN+10], step[MAXN+10];
LL L, R, K;
int count(int x)
{
	int ans = 0;
	while(x) x -= x & (-x), ans++;
	return ans;
}
struct Node {
	LL A[MAXN+10];
	Node operator - (const Node &t) const {
		Node now; 
		for(int i = 1; i <= MAXN; i++) now.A[i] = A[i] - t.A[i];
		return now;
	}
	void add (const Node &t, int pre) {
		for(int i = 0; i <= MAXN - pre; i++)
			A[i+pre] += t.A[i];
	}
} d[MAXN+10];
Node solve(LL X)
{
	int Len = 0, pre = 0;
	Node ans; memset(ans.A, 0, sizeof(ans.A));
	while(X) {
		bit[++Len] = X & 1;
		X >>= 1;
	}
	for(int i = Len; i >= 1; i--)
		if(bit[i])
			ans.add(d[i-1], pre++);
	ans.A[pre]++;
	return ans;
}
void init()
{
	for(int i = 0; i <= MAXN; i++) d[i].A[0] = 1;
	for(int i = 1; i <= MAXN; i++)
	{
		memcpy(d[i].A, d[i-1].A, sizeof(d[i].A));
		d[i].add(d[i-1], 1);
		step[i] = step[count(i)]+1;
	}
}
int main()
{
	init();
	while(cin >> L >> R >> K && L+R+K)
	{   LL ans = 0;
		if(K == 0 && L == 1) { puts("1"); continue; }
		if(K == 1 && L == 1) ans--;
		Node r = solve(R);
		Node l = solve(L-1);
		r = r - l;
		for(int i = 1; i <= MAXN; i++) if(step[i] == K) ans += r.A[i];
		cout << ans << '\n';
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值