原题来自:NEERC 2000 Central Subregional,题面详见 Ural 1057。
求给定区间 [X,Y]中满足下列条件的整数个数:这个数恰好等于 K个互不相等的 B 的整数次幂之和。例如,设 X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足题意:
17=2^4+2^0 18=2^4+2^1 20=2^4+2^2
Input
第一行包含两个整数 X 和 Y,接下来两行包含整数 K 和 B。
Output
只包含一个整数,表示满足条件的数的个数。
Example
样例输入
15 20
2
2
样例输出
3
Hint
对于全部数据,1≤X≤Y≤231−1,1≤K≤20,2≤B≤10。
#include<bits/stdc++.h> using namespace std; int read() { int x=0; int f=1; char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } const int maxn=31; int a[maxn][maxn]; int n,m,k,b; void inint(){ a[0][0]=1; for(int i=0;i<=maxn;i++){ a[i][0]=1; for(int j=1;j<=i;j++){ a[i][j]=a[i-1][j]+a[i-1][j-1]; } } } int dp(int n){ if(n==0){ return 0; } vector<int>nums; while(n){ nums.push_back(n%b),n/=b; } int last=0; int res=0; for(int i=nums.size()-1;i>=0;i--){ int x=nums[i]; if(x){//左边 res+=a[i][k-last]; if(x>1){ res+=a[i][k-last-1]; break; } else if(x==1){ last++; if(last>k){ break; } } } if(last>k){ break; } if(!i&&last==k){ res++; } } return res; } int main(){ inint(); cin>>n>>m>>k>>b; cout<<dp(m)-dp(n-1)<<endl; }