码迷,mamicode.com
首页 > 其他好文 > 详细

Amount of Degrees

时间:2020-04-12 18:32:32      阅读:56      评论:0      收藏:0      [点我收藏+]

标签:pos   保存   memset   hint   pen   def   区间   i++   mat   

Amount of Degrees

题目描述

求给定区间\([X,Y]\)中满足下列条件的整数个数:这个数恰好等于\(K\)个互不相等的 的整数次幂之和。例如,设\(X=15, Y=20, K=2, B=2\) ,则有且仅有下列三个数满足题意:

\(17 = 2^4+2^0\)

\(18 = 2^4 + 2^1\)

\(20 = 2^4+2^2\)

输入格式

第一行包含两个整数\(X\)\(Y\),接下来两行包含整数\(K\)\(B\)

输出格式

第一行包含两个整数 和 ,接下来两行包含整数 和 。

样例输入

15 20
2
2

样例输出

3

Hint

对于全部数据,\(1 \leq X \leq Y \leq 2^{31}-1,1 \leq K \leq 20,2 \leq B \leq 10\)

思路

以二进制为例,统计整数次幂个数也就是代表对应进制下1的个数,我么可以确定一个对用数位的二叉树,每层保存一个数位,左0右1,这样就可以列出所有数,之后在这颗树上记忆化搜索,初始化将符合条件的树记录,则有一个递推式:\(cnt[i][j] = cnt[i-1][j]+cnt[i-1][j-1]\),搜索时,每次移动到右子树则统计左子树的符合条件的结果。

Code

/**********************************************************
* @Author: 			   Kirito
* @Date:   			   2020-04-12 15:40:43
* @Last Modified by:   Kirito
* @Last Modified time: 2020-04-12 17:08:04
* @Remark: 
**********************************************************/
#include <bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define CSE(x,y) memset(x,y,sizeof(x))
#define INF 0x3f3f3f3f
#define Abs(x) (x>=0?x:(-x))
#define FAST ios::sync_with_stdio(false);cin.tie(0);
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll , ll> pll;

const int maxn=35;
int cnt[maxn][maxn], digit[maxn];
int x, y, b, k;

void ini()
{
	CSE(cnt, 0);
	cnt[0][0] = 1;
	for(int i = 1; i <= 32; i++)
	{
		cnt[i][0] = cnt[i - 1][0];
		for(int j = 1; j <= i; j++)
		{
			cnt[i][j] = cnt[i - 1][j] + cnt[i - 1][j - 1];
		}
	}
	return;
}

int get_ans(int x, int k)
{
	int pos = 1;
	while(x)
	{
		digit[pos++] = x % b;
		x /= b;
	}
	int ans = 0; pos -= 1;
	while(pos >= 1)//因为会用到pos - 1,所以这里用从1开始的下标
	{
		if(digit[pos] > 1){//如果该位大于1,则比此位数小的所有含有k个1的均成立,直接计算
			ans += cnt[pos - 1][k] + cnt[pos - 1][k -1];
			break;
		}
		else if(digit[pos] == 1)//此位为1,那么考虑下一位含有k - 1个1的情况
		{
			ans += cnt[pos - 1][k];
			k--;
		}
		if(k < 0)//已经找到k个1则直接退出
			break;
		pos--;
	}
	return ans;
}

int main()
{
	#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
	#endif
	FAST;
	ini();
	while(cin >> x >> y >> k >> b)
	{
		cout << get_ans(y + 1, k) - get_ans(x, k) << endl;
	}
	return 0;
}

Amount of Degrees

标签:pos   保存   memset   hint   pen   def   区间   i++   mat   

原文地址:https://www.cnblogs.com/LeafLove/p/12686482.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!