• I. Rooted Tree


    I. Rooted Tree

    整数拆分

    参考博客

    五边形数定理

    wiki

    这里的欧拉函数 (phi(q)) 是复变函数

    [phi(q) = prod_{k=1}^infty (1-q^k) ]

    五边形数定理描述了欧拉函数的展开式特性

    [(1-x)(1-x^2)(1-x^3)... = 1 -x-x^2+x^5+x^7-x^{12}-x^{15}+x^{22}+x^{26}+... ]

    欧拉函数展开后,有些次方项被消去,只留下次方项为1, 2, 5, 7, 12, ...的项次,留下来的次方恰为广义五边形数

    拆分函数 (p(n))

    [sum_{n=0}^{infty}p(n)x^n = prod_{k=1}^{infty}(frac{1}{1-x^k}) ]

    [1取了多少次->(1+x^1+x^2+x^3+…) \ 2取了多少次->(1+x^2+x^4+x^6+…) \ 3取了多少次->(1+x^3+x^6+x^9+…) \ vdots \ sum_{n=0}^{infty}p(n)x^n = (1+x^1+x^2+x^3+…)(1+x^2+x^4+x^6+…)(1+x^3+x^6+x^9+…) cdots ]

    根据欧拉发现的五边形数定理,描述欧拉函(ϕ(x))如下:

    [prod_{n=1}^{infty}(1-x^n) = sum_{k=-infty}^{infty} (-1)^kx^{k(3k-1)/2} = sum_{k=0}^{infty} (-1)^kx^{k(3k pm 1)/2} \ (1-x)(1-x^2)(1-x^3) … = 1-x-x^2+x^5+x^7-x^{12}-x^{15}+x^{22}+x^{26}+… \ 这些系数都属于广义五边形数 ]

    那么我们就很容易发现欧拉函数的导数是分割函数的母函数:

    [frac{1}{phi(x)} = sum_{k=0}^{infty} p(k)x^k quad <=> quad 1 = phi(x)sum_{k=0}^{infty} p(k)x^k \ (1-x-x^2+x^5+x^7-x^{12}-x^{15}+x^{22}+x^{26}+…)(1+p(1)x+p(2)x^2+p(3)x^3+…) = 1 ]

    那么在考虑(x^n)项的系数的时候,在(n>0)的情况下,系数都为0,那么就能得到

    [p(n)-p(n-1)-p(n-2)+p(n-5)+p(n-7)+… = 0 \ p(n) = p(n-1)+p(n-2)-p(n-5)-p(n-7)+ … ]

    这个的时间复杂度可以在O(nlogn)时间内解决。

    暂时不知道怎么 (nlogn) 搞,好像要多项式求逆啥的

    待补

    但是可以 (O(nsqrt n))

    #include <iostream>
    using namespace std;
    typedef long long ll;
    const ll N = 500005, mod = 998244353;
    ll f[N], g[N], dp[N];
    int n;
    
    int main() {
        scanf("%d", &n);
        --n;
        for (ll i = 1; i <= n; ++i) f[i] = i * (3*i - 1) / 2;
        for (ll i = 1; i <= n; ++i) g[i] = i * (3*i + 1) / 2;
        dp[0] = 1;
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; f[j] <= i; ++j) {
                if (j & 1) {
                    dp[i] += dp[i - f[j]];
                    if (g[j] <= i) dp[i] += dp[i - g[j]];
                } else {
                    dp[i] -= dp[i - f[j]];
                    if (g[j] <= i) dp[i] -= dp[i - g[j]]; 
                }
            }
            dp[i] %= mod;
            if (dp[i] < 0) dp[i] += mod;
        }
        printf("%lld
    ", dp[n]);
        return 0;
    }
    
  • 相关阅读:
    linux下的磁盘挂载
    shell中的循环语句while
    hadoop安装和配置
    shell 命令 创建/删除 软连接 ln -s
    azkaban disable 停用部分工作流
    git dev 分支merge到master
    shell 命令 zip unzip
    git代码同步服务器代码需要注意的问题
    shell 命令 if elif else fi 用法
    python 引入本地 module
  • 原文地址:https://www.cnblogs.com/sduwh/p/13775688.html
Copyright © 2020-2023  润新知