【URAL 1057】 Amount of Degrees 【数位DP】
2016-03-29 16:31
399 查看
1057. Amount of Degrees
Time limit: 1.0 secondMemory limit: 64 MB
Create a code to determine the amount of integers, lying in the set [X;Y] and being a sum of exactly K different integer degrees of B.
Example. Let X=15, Y=20, K=2, B=2. By this example 3 numbers are the sum of exactly two integer degrees of number 2:
17 = 24+20,
18 = 24+21,
20 = 24+22.
Input
The first line of input contains integers X and Y, separated with a space (1 ≤ X ≤ Y ≤ 231−1).The next two lines contain integers K and B(1 ≤ K ≤ 20; 2 ≤ B ≤ 10).
Output
Output should contain a single integer — the amount of integers, lying betweenX and Y, being a sum of exactly K different integer degrees of B.Sample
input | output |
---|---|
15 20 2 2 | 3 |
首先这个区间是满足区间减法的。因此我们可以只考虑,[0,y] 和 [0,x-1] 这两个区间内的个数。
再考虑这些数的性质, 这些数转化成b进制以后,每一数位上的值都是0或1;
那么就可以在数位上下手。然后我们就可以建一棵完全二叉树,完全二叉树的节点上依次填写0和1,这
样子,从根到叶子节点的路径就可以表示一个值。对于我们想要的数字,就是这条路径上的1的个数必须
是k个。对于各个子问题,我们可以预先处理处,到第i层有j个1。这个就是一个简单的dp。
然后对于b进制,我们可以把n 转化成b进制之后,去找一个不超过n最大的满足条件的数,在把b进制直
接当成2进制来做就可以。怎么去找这个‘最大’的数呢?就只在把n转化为b进制之后,从左边开始找到
第一个数位上不为0或1的位置,再把这个位置,和这个位置右边的所有数位上的值改为1。就可以了。
#include<stdio.h> #include<string.h> #include<algorithm> #include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<iostream> #include<stdlib.h> #include<set> #include<map> #include<queue> #include<stack> #include<vector> #include<bitset> #pragma comment(linker, "/STACK:1024000000,1024000000") #define inf 1073741824 #define llinf 4611686018285162540LL #define eps 1e-8 #define mod 9223372034707292160LL #define pi acos(-1.0) #define lth (th<<1) #define rth (th<<1|1) #define rep(i,a,b) for(int i=a;i<=b;i++) #define drep(i,a,b) for(int i=a;i>=b;i--) #define mset(x,val) memset(x,val,sizeof(x)) #define findx(x) lower_bound(b+1,b+1+bn,x)-b #define mpii(a,b) make_pair(a,b); #define NN 101010 #define MM 202020 using namespace std; typedef long long ll; typedef long double lb; typedef pair<int,int> pii; int n,m; int dp[33][33],b,k; void init(){ dp[0][0]=1; rep(i,1,31){ dp[i][0]=dp[i-1][0]; rep(j,1,i) dp[i][j]=dp[i-1][j]+dp[i-1][j-1]; } } int Go_Aquarion(int x,int k){ int ans=0,tot=0; drep(i,31,1){ if(x&(1<<i)){ tot++; if(tot>k) break; x^=(1<<i); } if((1<<(i-1))<=x){ ans+=dp[i-1][k-tot]; } } if(tot+x==k) ans++; return ans; } int transfer(int x,int b){ int bit[33],pt=0; mset(bit,0); while(x>0){ bit[++pt]=x%b; x/=b; } int flag=0; drep(i,pt,1){ if(flag==1) {bit[i]=1;continue;} if(bit[i]>1){ flag=1; bit[i]=1; } } int sum=0; rep(i,1,pt){ if(bit[i]==1) sum|=1<<(i-1); } return sum; } int main(){ scanf("%d%d",&n,&m); n--; init(); scanf("%d%d",&k,&b); int l,r; l=transfer(n,b); r=transfer(m,b); printf("%d\n",Go_Aquarion(r,k)-Go_Aquarion(l,k)); return 0; }
相关文章推荐
- c#LINQ学习
- enum推荐使用模型
- Android跳转系统界面_大全集
- java.lang.Object.clone()分析
- jvm学习笔记(一)—Java虚拟机内存区域
- Spark安装
- 《Linux内核设计与实现》读书笔记四
- 人脑功能连接组:计算方法学、重测信度及发展轨线(左西年,2011年)
- 像素翻转
- js一对多,添加属性
- ListView详解
- Android Volley框架使用详解
- iOS 关于如何将cell.detailTextLabel.text的内容显示出来的问题。
- R语言apply函数族笔记
- ios设计的神细节
- HDU 1194 Beat the Spread!(数学问题呀..)
- Caffe学习笔记
- 免费的论文查重网站
- JAVA 多线程随笔 (一) 可见性和volatile关键字
- CSS:IE,Chrome,Firefox兼容性和CSS Hack(转载)