[UVALive4864] Bit Counting && 数位DP

来源:互联网 发布:java面试专业技能 编辑:程序博客网 时间:2024/05/22 13:40

可以很容易的发现从N1开始的所有值都小于64 那么其实就是统计二进制中1的个数为1 ~ 63的数字各有多少

#include<cstdio>    #include<algorithm>    #include<cstring>    #include<vector>    #include<queue>  #include<deque>  #include<iostream>#define SF scanf    #define PF printf    using namespace std;typedef long long LL;const int MAXN = 64;int bit[MAXN+10], step[MAXN+10];LL L, R, K;int count(int x){int ans = 0;while(x) x -= x & (-x), ans++;return ans;}struct Node {LL A[MAXN+10];Node operator - (const Node &t) const {Node now; for(int i = 1; i <= MAXN; i++) now.A[i] = A[i] - t.A[i];return now;}void add (const Node &t, int pre) {for(int i = 0; i <= MAXN - pre; i++)A[i+pre] += t.A[i];}} d[MAXN+10];Node solve(LL X){int Len = 0, pre = 0;Node ans; memset(ans.A, 0, sizeof(ans.A));while(X) {bit[++Len] = X & 1;X >>= 1;}for(int i = Len; i >= 1; i--)if(bit[i])ans.add(d[i-1], pre++);ans.A[pre]++;return ans;}void init(){for(int i = 0; i <= MAXN; i++) d[i].A[0] = 1;for(int i = 1; i <= MAXN; i++){memcpy(d[i].A, d[i-1].A, sizeof(d[i].A));d[i].add(d[i-1], 1);step[i] = step[count(i)]+1;}}int main(){init();while(cin >> L >> R >> K && L+R+K){   LL ans = 0;if(K == 0 && L == 1) { puts("1"); continue; }if(K == 1 && L == 1) ans--;Node r = solve(R);Node l = solve(L-1);r = r - l;for(int i = 1; i <= MAXN; i++) if(step[i] == K) ans += r.A[i];cout << ans << '\n';}}


0 0
原创粉丝点击