计算2的次幂拆分为其他低次幂的方案数

高位2次幂拆分为低次幂

1、假设我们处于二进制第 \(i\) 位,现在想知道拆分为任意个 \(2^0,2^1,...,2^i\),即 \(x_0\times 2^0+x_1\times 2^1+...+x_d\times 2^d=2_i\),其中 \(0\le x_i\le +\infty\),问有多少种方案满足要求。

2、令 \(f(i,j,k)\) 表示将 \(2^i\) 拆分为若干 \(2\) 的次幂,最高次幂为 \(k\),最低次幂为 \(j\);令 \(F(i,j,k)\) 表示将 \(2^i\) 拆分为若干 \(2\) 的次幂,最高次幂不超过 \(k\),最低次幂为 \(j\),那么有:

  • \(f(i,j,k)=\sum_{x=j}^{k}F(i-1,j,x)\times f(i-1,x,k)\)

  • \(F(i,j,k)=F(i,j,k-1)+f(i,j,k)\)

3、若位数最大为 \(n\),则时间复杂度为:\(O(n^3)\),常数差不多为 \(6\)\(10\) 的样子。

4、\(Code:\)

const int N = 100;
i64 f[N + 1][N + 1][N + 1], F[N + 1][N + 1][N + 1];
void init() {
    f[0][0][0] = 1;
    for (int k = 0; k <= N; k++) F[0][0][k] = 1;
    int sum = 0;
    for (i64 i = 1; i <= N; i++) {
        for (i64 j = 0; j <= i; j++) {
            f[i][j][j] = (i == j);
            for (i64 k = j; k <= i; k++) {
                for (i64 x = j; x <= k; x++) {
                    sum++;
                    f[i][j][k] += F[i - 1][j][x] * f[i - 1][x][k] % mod;
                }
                f[i][j][k] %= mod;
            }
            F[i][j][j] = f[i][j][j];
            for (i64 k = j + 1; k <= N; k++) {
                F[i][j][k] = F[i][j][k - 1] + f[i][j][k];
                F[i][j][k] %= mod;
            }
        }
    }
}
posted @ 2025-01-16 16:29  grape_king  阅读(29)  评论(0)    收藏  举报