一本通1649:【例 2】2^k 进制数

#include <cstdio>
#include <cstring>
using namespace std;
struct Node {
    int a[210], len;
    Node() {
        len = 1;
        memset(a, 0, sizeof(a));
    }
};
inline int mmax(int x, int y) {
    return x > y ? x : y;
}
inline int mmin(int x, int y) {
    return x < y ? x : y;
}
Node multiple(Node n1, int x) {
    Node no;
    no.len = n1.len;

    for (int i = 1; i <= no.len; i++)
        no.a[i] = n1.a[i] * x;

    for (int i = 1; i <= no.len; i++) {
        no.a[i + 1] += no.a[i] / 10;
        no.a[i] = no.a[i] % 10;
    }

    int i = no.len;

    while (no.a[i + 1] > 0) {
        i++;
        no.a[i + 1] += no.a[i] / 10;
        no.a[i] = no.a[i] % 10;
    }

    while ((no.a[i] == 0) && (i > 1))
        i--;

    no.len = i;
    return no;
}
Node division(Node n1, int x) {
    Node no;
    int s = 0;
    no.len = n1.len;

    for (int i = n1.len; i >= 1; i--) {
        no.a[i] = (s * 10 + n1.a[i]) / x;
        s = (s * 10 + n1.a[i]) % x;
    }

    int i = no.len;

    while ((no.a[i] == 0) && (i > 1))
        i--;

    no.len = i;
    return no;
}
Node plus(Node n1, Node n2) {
    Node no;
    no.len = mmax(n1.len, n2.len);

    for (int i = 1; i <= no.len; i++)
        no.a[i] = n1.a[i] + n2.a[i];

    for (int i = 1; i <= no.len; i++) {
        no.a[i + 1] += no.a[i] / 10;
        no.a[i]      = no.a[i] % 10;
    }

    int i = no.len;

    while (no.a[i + 1] > 0) {
        i++;
        no.a[i + 1] += no.a[i] / 10;
        no.a[i]      = no.a[i] % 10;
    }

    while ((no.a[i] == 0) && (i > 1))
        i--;

    no.len = i;
    return no;
}
int main() {
    int w, k;
    scanf("%d%d", &k, &w);
    Node s;
    int n = (1 << k) - 1;
    int l = mmin(w / k, n - 1);
    Node C;
    C.a[1] = 1;
    C = multiple(C, n);

    for (int i = 2; i <= l; i++) {
        C = division(multiple(C, n - i + 1), i);
        s = plus(s, C);
    }

    Node ss;
    int ll = mmin((1 << w % k) - 1, n - l);

    if (l < w / k)
        ll = n - l;

    for (int i = 1; i <= ll; i++) {
        C = division(multiple(C, n - i - l + 1), n - i + 1);
        ss = plus(ss, C);
    }

    Node vx = plus(s, ss);

    for (int i = vx.len; i >= 1; i--)
        putchar(vx.a[i] + '0');

    putchar('\n');
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值