#zHSXybttg060602. 1649:【例 2】2^k 进制数

1649:【例 2】2^k 进制数

1649:【例 2】2^k 进制数

题目描述

rr 是个 2k2^k 进制数,并满足以下条件:

  1. rr 至少是个 22 位的 2k2^k 进制数。
  2. 作为 2k2^k 进制数,除最后一位外,rr 的每一位严格小于它右边相邻的那一位。
  3. rr 转换为 22 进制数 qq 后,qq 的总位数不超过 ww

在这里,正整数 kkww 是事先给定的。

问:满足上述条件的不同的 rr 共多少个?

输入格式

输入只一行,为两个正整数 kkww

输出格式

输出为一行,是一个正整数,为所求的计算结果,即满足条件的不同的 rr 的个数(用十进制数表示,要求最高位不得为 00,各数字之间不得插入数字以外的其他字符。

提示:作为结果的正整数可能很大,但不会超过 200200 位。

样例

样例输入 #1

3 7

样例输出 #1

36

样例解释 #1

  • k=3k=32k=82^k = 8,所以 rr88 进制数。
  • w=7w=7 表示 rr 转换为二进制后位数不超过 77
  • 条件 22rr 的每一位严格递增(除最后一位外,实际上最后一位与前面也满足严格递增?条件说“除最后一位外”,意思是最后一位没有右边相邻位,所以不要求最后一位比前一位大?但整个数是从左到右严格递增的,所以最后一位比前一位大也是成立的。实际上条件:每一位严格小于它右边相邻的那一位,所以对于最后一位,没有右边相邻位,所以没有约束。因此整个序列是严格递增的。
  • 求满足条件的 rr 的数量。
  • 输出 3636

数据范围

对于所有数据,1k91 \le k \le 9k<w3×104k < w \le 3 \times 10^4

时空限制

  • 时间限制:1000 ms
  • 内存限制:524288 KB

注意:本题是组合计数问题。rr 是一个 2k2^k 进制数,每一位数字在 002k12^k-1 之间,且从左到右严格递增(即数字单调递增)。同时,rr 转换为二进制后长度不超过 ww

2k2^k 进制数的最大位数为 LL。由于二进制位数不超过 ww,而 2k2^k 进制每一位对应 kk 位二进制(除了最高位可能不足 kk 位),所以有:rr 的位数 lenlen 满足:(len1)×k<wlen×k(len-1) \times k < w \le len \times k?实际上,rr 的二进制位数等于 rr 的位数乘以 kk,但最高位可能不足 kk 位(因为 rr 的位数固定时,最高位的取值范围可能使得二进制位数减少)。更精确地,设 rrmm 位,则 rr 的二进制位数最多为 m×km \times k,最少为 (m1)×k+1(m-1) \times k + 1(因为最高位至少为 11,所以二进制表示至少 11 位)。条件要求二进制位数不超过 ww,所以 mm 必须满足 (m1)×k+1w(m-1) \times k + 1 \le w,即 m(w1)/k+1m \le \lfloor (w-1)/k \rfloor + 1。另外,rr 至少 22 位,所以 m2m \ge 2

此外,由于 rr2k2^k 进制数,每一位数字在 002k12^k-1 之间,且严格递增(即各位数字互不相同且递增)。这相当于从 0,1,2,,2k10,1,2,\dots,2^k-12k2^k 个数字中选出 mm 个组成一个递增序列(即组合数),但最高位不能为 00(因为 rr2k2^k 进制数,最高位不能为 00,否则就不是 mm 位数了)。所以实际上,rr 对应一个从 112k12^k-1 中选出 mm 个不同数字并按升序排列,但数字顺序就是数位顺序,所以每个组合对应一个 rr。因此,对于固定的 mm,方案数为 C(2k1,m)C(2^k-1, m)(因为最高位不能为 00,所以不能选 00,从 112k12^k-12k12^k-1 个数中选 mm 个)。

但还需要考虑二进制位数不超过 ww 的限制。当 mm 固定时,rr 的二进制位数等于 m×km \times k 减去前导零的个数?实际上,rr 的二进制表示就是将其每一位数字表示为 kk 位二进制(最高位可能不足 kk 位,因为最高位的数字可能小于 2k12^{k-1},但二进制位数仍是 kk 位?例如 k=3k=3,数字 11 的二进制是 001001,但作为二进制数 qq,前导零可以去掉,所以 qq 的位数可能小于 m×km \times k。但题目中“转换为 22 进制数 qq 后,qq 的总位数不超过 ww”是指去掉前导零后的位数。所以我们需要确保 rr 的二进制表示去掉前导零后长度不超过 ww

由于 rr 的最高位不为 00,设为 xx,则 x1x \ge 1,其二进制表示的长度为 log2x+1\lfloor \log_2 x \rfloor + 1,这个长度可能小于 kk。其余 m1m-1 位每个都恰好占用 kk 位二进制(因为即使数字小于 2k12^{k-1},在 2k2^k 进制表示中我们仍然用 kk 位表示,但转换为二进制时会去掉前导零?实际上,rr 转换为二进制数 qq 的过程是:将 rr 的每一位数字写成二进制,然后拼接起来,去掉最高位的前导零,但中间位的前导零不能去掉(因为它们是 kk 位的一部分)。所以 qq 的总位数 = (m1)×k+(最高位二进制位数)(m-1) \times k + (\text{最高位二进制位数})

设最高位数字为 xx,其二进制位数 lenx=log2x+1len_x = \lfloor \log_2 x \rfloor + 1,则 qq 的总位数为 (m1)×k+lenx(m-1) \times k + len_x。条件要求 (m1)×k+lenxw(m-1) \times k + len_x \le w

由于 xx 的取值范围是 112k12^k-1lenxlen_x 可能为 11kk。因此,对于固定的 mm,我们需要计算满足 (m1)×k+lenxw(m-1) \times k + len_x \le w1x2k11 \le x \le 2^k-1xx 的个数,然后乘以从剩余数字中选出 m1m-1 个且大于 xx 的组合数。

但这样计算较复杂。另一种思路:先不考虑二进制位数限制,计算所有满足严格递增且最高位非 002k2^k 进制数的个数,然后减去那些二进制位数超过 ww 的数。

由于 k9k \le 92k5122^k \le 5122k12^k-1 不大,但 ww 可能很大(3×1043\times 10^4),所以 mm 的最大值可能很大(m(w1)/k+1m \le \lfloor (w-1)/k \rfloor + 1,最大约 30000/1=3000030000/1=30000)。但 2k12^k-1 最多 511511,所以当 m>2k1m > 2^k-1 时,无法选出 mm 个不同数字,方案数为 00。因此,实际上 mm 不超过 2k12^k-1

所以我们可以枚举 mm22min(2k1,(w1)/k+1)\min(2^k-1, \lfloor (w-1)/k \rfloor + 1),对于每个 mm,计算方案数。

但还需要考虑二进制位数限制:对于每个 mm,最高位数字 xx 必须满足 (m1)×k+lenxw(m-1) \times k + len_x \le w。由于 lenxlen_x 取决于 xx 的大小,我们可以按 lenxlen_x 分类。

t=w(m1)×kt = w - (m-1) \times k,则要求 lenxtlen_x \le tlenxlen_xxx 的二进制位数,xx112k12^k-1 之间。设 cnt[l]cnt[l] 表示二进制位数为 ll 的数字个数(1lk1 \le l \le k),则 cnt[l]=2l1cnt[l] = 2^{l-1}(因为首位为 11,后面 l1l-1 位任意),但当 l=kl=k 时,最大数字为 2k12^k-1,所以 cnt[k]=2k1cnt[k] = 2^{k-1}?实际上,二进制位数为 ll 的数字范围是 2l12^{l-1}2l12^l-1,共 2l12^{l-1} 个。对于 l=kl=k,范围是 2k12^{k-1}2k12^k-1,共 2k12^{k-1} 个。但注意 xx 不能超过 2k12^k-1,所以 l=kl=k 时确实是 2k12^{k-1} 个。

因此,满足 lenxtlen_x \le txx 的个数为 l=1min(t,k)cnt[l]\sum_{l=1}^{\min(t, k)} cnt[l],但 tt 可能大于 kk,此时所有 xx 都满足(因为 lenxklen_x \le k),所以个数为 2k12^k - 1(所有非零数字)。

对于每个这样的 xx,我们需要从大于 xx 的数字中选出 m1m-1 个(因为后面数字必须严格大于 xx),且总数字范围是 112k12^k-1,大于 xx 的数字有 2k1x2^k-1 - x 个,所以方案数为 C(2k1x,m1)C(2^k-1 - x, m-1)

因此,对于固定的 mm,总方案数为:

$$\sum_{x=1}^{2^k-1} [len_x \le t] \cdot C(2^k-1 - x, m-1)$$

其中 t=w(m1)kt = w - (m-1)k

由于 2k12^k-1 最多 511511,可以直接枚举 xx 计算组合数。但组合数可能很大,需要高精度计算(因为答案可能很大,不超过 200200 位,所以需要高精度加法和高精度组合数)。

另外,mm 可能达到 511511,组合数 C(n,m)C(n,m) 可以用递推公式 C(n,m)=C(n1,m1)+C(n1,m)C(n,m) = C(n-1,m-1) + C(n-1,m) 计算,但需要高精度。

由于 k9k \le 92k15112^k-1 \le 511,所以我们可以预处理所有组合数 C(i,j)C(i,j)0ji5110 \le j \le i \le 511),用高精度存储。然后枚举 mmxx 累加。

注意:tt 可能小于 11,此时没有满足条件的 xx,方案数为 00

算法步骤:

  1. 读入 k,wk, w
  2. 计算 maxm=min(2k1,(w1)/k+1)maxm = \min(2^k-1, \lfloor (w-1)/k \rfloor + 1),且 m2m \ge 2
  3. 预处理高精度组合数表 C[i][j]C[i][j]0ji5110 \le j \le i \le 511)。
  4. 初始化答案 ans=0ans = 0(高精度)。
  5. 枚举 mm22maxmmaxm
    • 计算 t=w(m1)×kt = w - (m-1) \times k
    • 如果 t<1t < 1,跳过。
    • 枚举 xx112k12^k-1
      • 计算 lenx=log2x+1len_x = \lfloor \log_2 x \rfloor + 1
      • 如果 lenx>tlen_x > t,继续。
      • 计算 n=2k1xn = 2^k - 1 - x
      • 如果 n<m1n < m-1,跳过。
      • ans+=C[n][m1]ans += C[n][m-1](高精度加法)。
  6. 输出 ansans(高精度数,无前导零)。

注意:当 tkt \ge k 时,所有 xx 都满足 lenxtlen_x \le t,此时可以简化计算:方案数为 x=12k1C(2k1x,m1)\sum_{x=1}^{2^k-1} C(2^k-1 - x, m-1)。令 y=2k1xy = 2^k-1 - x,则 yy002k22^k-2,求和为 y=02k2C(y,m1)\sum_{y=0}^{2^k-2} C(y, m-1)。根据组合恒等式 y=m12k2C(y,m1)=C(2k1,m)\sum_{y=m-1}^{2^k-2} C(y, m-1) = C(2^k-1, m)(因为 C(m1,m1)+C(m,m1)+...+C(n,m1)=C(n+1,m)C(m-1,m-1) + C(m,m-1) + ... + C(n,m-1) = C(n+1, m))。注意 yy00 开始,但 C(y,m1)C(y, m-1)y<m1y < m-1 时为 00,所以实际上求和为 C(2k1,m)C(2^k-1, m)。因此,当 tkt \ge k 时,方案数就是 C(2k1,m)C(2^k-1, m)。这对应于二进制位数限制不起作用的情况(因为最高位二进制位数最多 kk,而 tkt \ge k 意味着 (m1)k+kw(m-1)k + k \le w,即 mkwmk \le w,所以整个数的二进制位数不超过 ww)。

因此,我们可以分两种情况:

  • 如果 m×kwm \times k \le w,则方案数为 C(2k1,m)C(2^k-1, m)
  • 否则,方案数为 $\sum_{x=1}^{2^k-1} [len_x \le w - (m-1)k] \cdot C(2^k-1 - x, m-1)$。

由于 kk 很小,可以直接枚举 xx

高精度实现:可以用数组存储十进制位,实现加法和组合数递推。

注意:答案可能很大,但不超过 200200 位,所以高精度数组大小可以设为 300300