数位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 ",calc(r)-calc(l-1)) ; 55 return 0 ; 56 }