数位DP 

求给定区间[X,Y]中满足下列条件的整数个数:
这个数恰好等于K个互不相等的B的整数次幂之和

 1 #include <cstdio> 
 2 #include <cmath>
 3 #define LL long long 
 4 #define For(i,j,k) for(int i=j;i<=k;i++) 
 5 #define Dow(i,j,k) for(int i=j;i>=k;i--) 
 6 using namespace std ; 
 7 
 8 const int N = 1011,M = 10011 ;
 9 int l,r,K,B ; 
10 LL f[32][32] ; 
11 int digit[32] ; 
12 
13 inline int read() 
14 {
15     int x = 0 , f = 1 ; 
16     char ch = getchar() ; 
17     while(ch<'0'||ch>'9') { if(ch=='-') f = -1 ; ch = getchar(); } 
18     while(ch>='0'&&ch<='9') { x = x * 10+ch-48 ; ch = getchar(); } 
19     return x * f ; 
20 }
21 
22 inline LL calc(int x) 
23 {
24     int len = 0,need = K ;  
25     LL ans = 0 ; 
26     if(x==0) digit[++len] = 0 ; 
27     while(x) {
28         digit[++len] =x%B ; 
29         x/=B ; 
30     }
31     int pos = 0 ; 
32     Dow(i,len,1) 
33         if(digit[i]>1) {
34             pos = i ; 
35             break ; 
36         }
37     Dow(i,pos,1) digit[i] = 1 ; 
38     Dow(i,len,1) {
39         if(digit[i]) ans+=f[i-1][need] ;  //
40         need-=digit[i] ; 
41         if(need==-1) break ; 
42     }
43     if(need==0) ans++ ; 
44     return ans ; 
45 }
46 
47 int main() 
48 {
49     f[0][0] = 1 ; 
50     For(i,1,31) 
51       For(j,0,i) f[i][j]=f[i-1][j-1]+f[i-1][j] ; 
52     
53     l = read() ; r = read() ; K = read() ; B = read() ; 
54     printf("%lld\n",calc(r)-calc(l-1)) ;  
55     return 0 ; 
56 }

 

posted @ 2017-10-01 17:31  third2333  阅读(161)  评论(0编辑  收藏  举报