一本通1585【例 1】Amount of Degrees
1585: 【例 1】Amount of Degrees
时间限制: 1000 ms 内存限制: 524288 KB
题目描述
原题来自: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
输入格式
第一行包含两个整数 X 和 Y,接下来两行包含整数 K 和 B。
输出格式
只包含一个整数,表示满足条件的数的个数。
样例
样例输入
15 20
2
2
样例输出
3
数据范围与提示
对于全部数据, 1≤X≤Y≤2^31−1,1≤K≤20,2≤B≤10。
sol:把一个数想象成一个有B进制表示但只有(0,1)组成的数,统计的时候把n拆成B进制,用组合数计算一下,如果那位数字>1的话就退出,如果=1的话就对于那位填(0,1)讨论一下
#include <bits/stdc++.h> using namespace std; inline int read() { int s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(int x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } inline void writeln(int x) { write(x); putchar('\n'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) writeln(x) int l,r,k,B; int C[40][40]; inline void Init() { int i,j; for(i=0;i<=39;i++) { C[i][0]=1; for(j=1;j<=i;j++) { C[i][j]=C[i-1][j]+C[i-1][j-1]; } } return; } /* 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 */ inline int Solve(int n) { int i,Len=0,ans=0,Now_k=k; int a[40]; while(n) { a[++Len]=n%B; n/=B; } for(i=Len;i>=1;i--) { if(a[i]==1) { ans+=C[i-1][Now_k]; Now_k--; } else if(a[i]>1) { ans+=C[i][Now_k]; break; } if(Now_k<0)return ans; } if(Now_k==0) ans++; return ans; } int main() { int i; Init(); R(l); R(r); R(k); R(B); Wl(Solve(r)-Solve(l-1)); return 0; } /* input 15 20 2 2 output 3 */
河田は河田、赤木は赤木……。
私は誰ですか。教えてください、私は誰ですか。
そうだ、俺はあきらめない男、三井寿だ!