1 条题解

  • 1
    @ 2026-9-6 11:38:29
    using namespace std;
    
    // 高精度整数:十进制 1e9 进制,小端存储
    struct BigInt {
        vector<int> d;
        BigInt() : d(1, 0) {}
        BigInt(int x) {
            if (x == 0) d.push_back(0);
            else {
                while (x) { d.push_back(x % 1000000000); x /= 1000000000; }
            }
        }
        void trim() { while (d.size() > 1 && d.back() == 0) d.pop_back(); }
    
        BigInt operator+(const BigInt& o) const {
            BigInt r;
            r.d.assign(max(d.size(), o.d.size()) + 1, 0);
            long long carry = 0;
            for (size_t i = 0; i < r.d.size(); i++) {
                long long s = carry;
                if (i < d.size()) s += d[i];
                if (i < o.d.size()) s += o.d[i];
                r.d[i] = (int)(s % 1000000000);
                carry = s / 1000000000;
            }
            r.trim();
            return r;
        }
        // 前提:*this >= o
        BigInt operator-(const BigInt& o) const {
            BigInt r;
            r.d.assign(d.size(), 0);
            long long borrow = 0;
            for (size_t i = 0; i < d.size(); i++) {
                long long s = (long long)d[i] - borrow - (i < o.d.size() ? o.d[i] : 0);
                if (s < 0) { s += 1000000000; borrow = 1; } else borrow = 0;
                r.d[i] = (int)s;
            }
            r.trim();
            return r;
        }
        void print() const {
            printf("%d", d.back());
            for (int i = (int)d.size() - 2; i >= 0; i--) printf("%09d", d[i]);
            printf("\n");
        }
    };
    
    int main() {
        int k, w;
        scanf("%d%d", &k, &w);
        int B = 1 << k;          // 2^k(k<=9,B<=512)
        int n = w / k, m = w % k;
    
        // 递推杨辉三角,只需保留上一行;快照第 B-1 行与第 B-2^m 行
        vector<BigInt> prev(1, BigInt(1)), rowB1, rowBmin;
        for (int top = 0; top <= B - 1; top++) {
            vector<BigInt> cur(top + 1, BigInt(0));
            cur[0] = BigInt(1);
            for (int j = 1; j <= top; j++)
                cur[j] = prev[j - 1] + (j < (int)prev.size() ? prev[j] : BigInt(0));
            if (top == B - 1) rowB1 = cur;
            if (m > 0 && top == B - (1 << m)) rowBmin = cur;
            prev = move(cur);
        }
    
        BigInt ans;
        for (int d = 2; d <= min(n, B - 1); d++) ans = ans + rowB1[d];
    
        if (m > 0) {
            // 补上 d = n+1 位的贡献:C(B-1, n+1) - C(B-2^m, n+1)
            BigInt a = (n + 1 <= B - 1) ? rowB1[n + 1] : BigInt(0);
            BigInt b = (n + 1 <= B - (1 << m)) ? rowBmin[n + 1] : BigInt(0);
            ans = ans + (a - b);
        }
        ans.print();
        return 0;
    }
    
    
    
    • 1

    信息

    ID
    690
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    递交数
    8
    已通过
    2
    上传者