UVaLive 6844 - Combination

来源:互联网 发布:校园网站源码 编辑:程序博客网 时间:2024/06/01 15:44

题意:输入一个low、high,求

这个题可以通过暴力小数据发现规律。对于一个数字n,如果这个数字的二进制有i个1,那么的值为2的i次方。然后用类似数位dp的方式统计结果。对于(1<<i),小于这个数有j个1的情况有C(i,j)个,对于每一个j先统计出有j位1的数字有多少个,然后计算结果。

#include <iostream>#include <cstdio>#include <cstring>using namespace std;typedef unsigned long long ll;ll pw[100];ll CCC(int u, int v) {    ll ans = 1;    for(ll i = 0; i < v; i++) {        ans = ans * (u - i) / (i + 1);    }    return ans;}ll deal(ll n) {    int x = 0;    memset(pw, 0, sizeof(pw));    for(int i = 63; i >= 0; i--) {        ll t = 1LL << i;        if((n & t) == 0) continue;        ll m = 1;        for(int j = 0; j <= i; j++) {            pw[j + x] += m;            m = m * (i - j) / (j + 1);        }        x++;    }    ll t = 1, ans = 0;    for(int i = 0; i < 64; i++) {        ans += t * pw[i];        t *= 2;    }    return ans;}int main() {    ll n, m;    while(~scanf("%llu%llu", &n, &m) && (n || m)) {        printf("%llu\n", deal(m + 1) - deal(n));    }    return 0;}


0 0
原创粉丝点击