首页 > 其他 > 详细

URAL 1057 Amount of Degrees(数位统计)

时间:2015-08-13 23:47:04      阅读:690      评论:0      收藏:0      [点我收藏+]
题意:


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

思路:对于二进制来说(图片摘自刘聪的浅谈数位类统计问题论文)

技术分享

现在推广到b进制

因为对于b进制的每一位,我们只需要讨论这一位是否是一,所以我们可以把这个数转换为一个等价的二进制数,

方法是将这个数从左到右第一位不是零或一的位变为1,并把其右边的所有位置一,求出这个二进制数。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#define eps 1e-6
#define LL long long
#define pii (pair<int, int>)
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

//const int maxn = 100 + 5;
//const int INF = 0x3f3f3f3f;
LL f[40][40];
int x, y, k, b;

void init() {
    f[0][0] = 1;
    for(int i = 1; i <= 31; i++) {
        f[i][0] = 1;
        for(int j = 1; j <= i; j++) {
            f[i][j] = f[i-1][j] + f[i-1][j-1];
        }
    }
}

int cal(int x, int k) {
    int tot = 0, ans = 0;
    for(int i = 31; i > 0; i--) {
        if((1<<i)&x) {
            tot++;
            if(tot > k) break;
            x ^= (1<<i);
        }
        if((1<<(i-1))<=x) {
            ans += f[i-1][k-tot];
        }
    }
    if(tot+x == k) ans++;
    return ans;
}

int conv(int x) {
    int ans = 0;
    vector<int> v;
    while(x) {
        v.push_back(x%b);
        x /= b;
    }
    int sz = v.size();
    for(int i = sz-1; i >= 0; i--) {
        if(v[i]==1 || !v[i]) {
            ans += (v[i]==0 ? 0 : (1<<i));
        }
        else {
            for(int j = 0; j <= i; j++) ans += (1<<j);
            break;
        }
    }
    return ans;
}
int main() {
    //freopen("input.txt", "r", stdin);
    init();
    while(scanf("%d%d%d%d", &x, &y, &k, &b) == 4) {
        //cout << conv(y) << endl << conv(x) << endl;
        cout << cal(conv(y), k)-cal(conv(x-1), k) << endl;
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

URAL 1057 Amount of Degrees(数位统计)

原文:http://blog.csdn.net/u014664226/article/details/47622549

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!